vue的插件iview、Element-UI表格功能还不够完善,Datatables(https://datatables.net/)是jQuery插件。本文使用iview+vue实现表格功能,也可适当修改适用于Element-UI。
通过axios等获取到所有后台数据后,实现的功能如下:
1) 分页:每页大小,总条数及当前项;
2) 搜索:全局搜索,或指定列搜索;
3) 多选:多页选择,返回已选择项,根据数据回显多页中的多个选项;
4) 其它iview已实现的功能,如自定义渲染当前列、数据过滤、导出数据等。
/* define_table.vue */
<template>
<div style="font-size:14px;">
<div class="clearfix" style="padding:10px 0;">
<!-- 每页大小 -->
<div style="float:left;">
显示
<Select v-model="pageSize" size="small" style="width:60px">
<Option v-for="item in pageSizeList" :value="item" :key="item">{{item}}</Option>
</Select>
项结果
</div>
<!-- 搜索 -->
<div style="float:right;">
搜索:
<Input v-model="keywords" size="small" style="width:180px" />
</div>
</div>
<!-- 表格 -->
<Table ref="TableList" :columns="cols" :data="currentPageData" stripe :loading="loading"
@on-select="selectItem" @on-select-cancel="selectItemCancel"
@on-select-all="selectAll" @on-select-all-cancel="selectAllCancel"></Table>
<!-- 分页 -->
<div class="clearfix" style="padding:10px 0;">
<div style="float:left;line-height:32px;">
显示第 {{start}} 至 {{end}} 项结果,
共 {{total}} 项
</div>
<Page style="float:right;" :total="total" :page-size="pageSize" :current="currentPage" show-elevator
@on-change="getCurrentPageData"></Page>
</div>
</div>
</template>
<script>
export default {
data () {
return {
pageSize:'', // 每页数量
currentPage:1, // 当前页
keywords:'', // 根据关键字筛选表格数据
loading:true, // 表格是否正在加载
allData:[], // 表格数据
filterData:[], // 表格筛选后的数据
currentPageData:[], // 表格当前页数据
selectedData:[], // 选中数据列表
}
},
props: {
url:{
type:String,
required:true,
},
cols:{
type:Array,
required:true,
},
pageSizeList:{
type:Array,
default:function () {
return [10,20,50,100,200,'all']
},
},
onlyKey:{
type:String,
default:'id'
},
},
computed: {
total(){ // 数据总数
return this.filterData.length;
},
start(){ // 列表当前页起始项编号
if(this.total==0){
return 0;
}
if(this.pageSize=='all'){
return 1;
}
return this.pageSize*(this.currentPage-1)+1;
},
end(){ // 列表当前页结束项编号
if(this.pageSize=='all'){
return this.total;
}
var sum=this.pageSize*this.currentPage;
return sum>this.total?this.total:sum;
}
},
watch:{
pageSize(){ // 下拉框改变每页数量大小
this.currentPage=1;
this.getCurrentPageData(1);
},
keywords(newVal){ // 文本框搜索数据
var _this=this;
/* 全局搜索 */
this.filterData=this.allData.filter(item=>{ // 对于每一行数据
var flag=false;
_this.cols.forEach(col=>{ // 获取每一列的key
if(col.hasOwnProperty('key')){ // 如果key不为undefined
var prop=col.key;
if(item[prop]){ // 如果该属性值不为undefined或null
if(item[prop].indexOf(newVal)>=0){
flag=true;
}
}
}
});
return flag;
});
/* 指定列搜索
this.filterData=this.allData.filter(item=>{ // 对于每一行数据
if(item.deviceIp.indexOf(newVal)>=0){ // 指定某属性过滤,如deviceIp
return true;
}
}); */
this.getCurrentPageData(1);
}
},
methods: {
getAllData(){ // 页面加载时获取表格所有数据
var _this=this;
util.ajaxMethodWidthParams(util.baseUrl+this.url, 'GET', {}).then(function(data){
// console.log(data)
_this.loading=false;
_this.allData=data;
_this.filterData=data;
_this.getCurrentPageData(1);
});
},
getCurrentPageData(page){ // 获取表格数据筛选后的当前页数据
this.currentPage=page;
this.currentPageData=this.filterData.slice(this.start-1,this.end);
},
clearChecked(){ // 循环列表数据,清空所有_checked:true
this.allData.forEach(item=>{
item._checked=false;
});
},
checkedRows(arr,key){ // 多选回显,arr为被选中的key属性值,table默认选中arr包含的值对应的行
this.allData.forEach(item=>{ // 循环列表数据,如果当前key属性值在arr中,添加_checked: true
if(arr.indexOf(item[key])>=0){
item._checked=true;
}
})
this.filterData=this.allData;
this.getCurrentPageData(1);
},
getCheckedData(){ // 获取多页中所有被选中的数据
return this.allData.filter(item=>{
if(item._checked){
return true;
}
});
},
selectItem(selection,row){ // 选中某一项时,修改allData中对应项的_checked为true
for(var i=0;i<this.allData.length;i++){
if(this.allData[i][this.onlyKey]==row[this.onlyKey]){
this.allData[i]._checked=true;
return;
}
}
},
selectItemCancel(selection,row){ // 取消选中某一项
for(var i=0;i<this.allData.length;i++){
if(this.allData[i][this.onlyKey]==row[this.onlyKey]){
this.allData[i]._checked=false;
return;
}
}
},
selectAll(selection){ // 全选
var keys=[];
selection.forEach(item=>{keys.push(item[this.onlyKey])});
for(var i=0;i<this.allData.length;i++){
if(keys.indexOf(this.allData[i][this.onlyKey])>=0){
this.allData[i]._checked=true;
}
}
},
selectAllCancel(selection){ // 取消全选
var keys=[];
selection.forEach(item=>{keys.push(item[this.onlyKey])});
for(var i=0;i<this.allData.length;i++){
if(keys.indexOf(this.allData[i][this.onlyKey])>=0){
this.allData[i]._checked=false;
}
}
},
},
created(){
this.pageSize=this.pageSizeList[0];
},
}
</script>
<style scoped>
.clearfix::after{
content:".";
display:block;
clear:both;
height:0;
visibility:hidden;
}
</style>