<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.17.1/axios.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
<style>
.pagination li a,th,.input-group-addon{
cursor: pointer;
}
</style>
</head>
<body>
<div id="app">
<table class="table">
<thead>
<tr>
<th v-for="column in showColumns" @click="sortBy(column)">
<span>{{ column }}</span>
<span v-if="sortByColumn == column">{{ directionSignal }}</span>
</th>
</tr>
</thead>
<tbody>
<tr v-for="item in thisPageShow">
<td v-for="column in showColumns">
<span>{{ item[column] }}</span>
</td>
</tr>
</tbody>
</table>
<div class="row">
<div class="col-md-6">
<ul class="pagination">
<li v-if="nowPage!=1 && totalPage>1">
<a @click.prevent="changePage(nowPage-1)"><</a>
</li>
<li v-for="page in pageNumber" :class="[page == nowPage ? 'active' : undefined]">
<a @click.prevent="changePage(page)">{{ page }}</a>
</li>
<li v-if="nowPage!=totalPage && totalPage>1">
<a @click.prevent="changePage(nowPage+1)">></a>
</li>
</ul>
</div>
<div class="col-md-3">
<select class="form-contorl" v-model="searchColumn">
<option v-for="column in showColumns">{{ column }}</option>
</select>
<div class="input-group">
<input type="text" class="form-control" v-model="searchInput">
<span class="input-group-addon" @click="searchTable">Search</span>
<span class="input-group-addon" @click="clearSearch">Clear</span>
</div>
</div>
<div class="col-md-3">
<div class="btn-group">
<button type="button" class="btn btn-primary" @click="whereQuery('gender','male')" :class="[whereQueryActive == 'male' ? 'active' : undefined]">male</button>
<button type="button" class="btn btn-primary" @click="whereQuery('gender','female')" :class="[whereQueryActive == 'female' ? 'active' : undefined]">female</button>
</div>
</div>
</div>
</div>
<script>
var app = new Vue({
el:'#app',
data:{
allDatas:[],
allDatasBackup:[],
perPage:10,
dataAfterCut:[],
totalPage:0,
thisPageShow:[],
nowPage:1,
offset:4,
firstPage:1,
lastPage:10,
showColumns:['cell','dob','email','gender'],
direction:'asc',
sortByColumn:'cell',
searchColumn:'cell',
searchInput:'',
whereQueryActive:''
},
created() {
this.fetchData();
},
computed:{
pageNumber() {
var arr = [];
for (let i = this.firstPage; i <= this.lastPage; i++) {
arr.push(i);
}
return arr;
},
directionSignal() {
if(this.direction == 'asc'){
return '↑';
}else if(this.direction == 'desc'){
return '↓';
}
},
},
methods:{
fetchData() {
var vm = this;
axios.get('https://randomuser.me/api/?results=300').then(function(rs){
vm.allDatasBackup = rs.data.results;
vm.allDatas = rs.data.results;
vm.setInitPage();
vm.cutArray();
});
},
cutArray() {
var vm = this;
vm.dataAfterCut = [];
for (let i = 0; i < vm.totalPage; i++) {
vm.dataAfterCut[i] = [];
vm.dataAfterCut[i].push(vm.allDatas.slice(vm.perPage * i, vm.perPage * (i + 1)));
}
vm.thisPageShow = vm.dataAfterCut[0][0];
},
setInitPage() {
var vm = this;
vm.totalPage = Math.ceil(vm.allDatas.length / vm.perPage);
if (vm.totalPage > vm.offset * 2 + 1) {
vm.lastPage = vm.offset * 2 + 1;
} else {
vm.lastPage = vm.totalPage;
}
},
changePage(page) {
this.thisPageShow = this.dataAfterCut[page-1][0];
this.nowPage = page;
if(this.nowPage+this.offset*2 >=this.lastPage){
this.firstPage = this.nowPage - this.offset;
this.lastPage = this.nowPage + this.offset;
}
//最後一頁的頁碼設定
if(this.firstPage > this.totalPage - this.offset * 2 ){
this.firstPage = this.totalPage - this.offset * 2;
this.lastPage = this.totalPage;
}
//不要變成負數
if(this.firstPage <1){ this.firstPage = 1};
//第一頁的頁碼設定
if(this.lastPage<this.offset *2+1){this.lastPage = this.offset*2 +1};
//不要超出最大頁碼
if(this.lastPage > this.totalPage){ this.lastPage = this.totalPage};
},
sortBy(column) {
this.sortByColumn = column;
if(this.direction == 'asc'){
this.direction = 'desc';
}else{
this.direction = 'asc';
}
this.allDatas = _.orderBy(this.allDatas,column,this.direction);
this.cutArray();
},
searchTable() {
this.allDatas = _.cloneDeep(this.allDatasBackup);
this.allDatas = this.allDatas.filter(rs=>rs[this.searchColumn].indexOf(this.searchInput)!=-1);
this.reArrangeData();
},
clearSearch() {
this.allDatas = _.cloneDeep(this.allDatasBackup);
this.searchInput = '';
this.setInitPage();
this.cutArray();
this.changePage(1);
},
whereQuery(type,value) {
this.allDatas = _.cloneDeep(this.allDatasBackup);
this.allDatas = this.allDatas.filter(rs => rs[type] == value);
this.reArrangeData();
this.whereQueryActive = value;
},
reArrangeData() {
this.whereQueryActive = '';
this.dataAfterCut = [];
this.thisPageShow = [];
this.firstPage = 1;
this.lastPage = 1;
this.totalPage = 1;
if (this.allDatas.length > 0) {
this.setInitPage();
this.cutArray();
this.changePage(1);
}
}
}
});
Vue.config.devtools = true;
</script>
</body>
</html>
2018年1月20日 星期六
用vue寫出:有頁碼表格,可排序,搜尋,限制出現之資料
訂閱:
張貼留言 (Atom)
沒有留言:
張貼留言