//引入vue-easytable
import '@/libs/vue-easytable/libs/themes-base/index.css';
import {VTable} from '@/libs/vue-easytable'
<!--
easyTable-扩展
ps:
1、数据来源 (头部、body)
2、功能:
列拖拽width改变
列左右拖拽
列头点击排序(sort权重)
sort权重排序(多列未完成)
全量数据模糊搜索
行hover/checked (hover消除)
td单独渲染dom
列显示隐藏(将header数据移除即可)
筛选访客类别
3、5000数据首次渲染(全量一次性渲染) 10s卡顿 可以分步渲染 达到1s内显示
-->
<template>
<div class="tablePage">
<!--<div class="pd-10">-->
<!--<label>搜索:<input class="searchInput" type="text" v-model="searchKeyWord" placeholder="请输入搜索内容"><i @click="searchClick" class="cursor-hand el-icon-search"></i></label>-->
<!--</div>-->
<!-- 渲染分类项
<el-checkbox-group v-model="checkList">
<el-checkbox style="display: block" v-for="op in CASList" :label="op.label" :key="op.label">{{op.value}}</el-checkbox>
</el-checkbox-group>
-->
<div class="pd-10 mgb-15">
<el-button type="warning" @click="getLocationData">拉取本地数据</el-button>
<el-button class="mgl-10" type="warning" @click="getYAPIData">拉取mock数据</el-button>
</div>
<!--getYAPIData-->
<!-- 表格-->
<v-table
column-width-drag
is-horizontal-resize
style="width:100%"
:columns="columns"
:table-data="tableData.filter(data => CAS === [] || (CAS.indexOf(data.CAS)>-1))"
row-hover-color="#eee"
row-click-color="#edf7ff"
:show-vertical-border="true"
:multiple-sort = "true"
sort-always
@sort-change="sortChange"
:is-vertical-resize="true"
:rowClick="rowClick"
></v-table>
</div>
</template>
<script>
import API from "@/api/demo"
import {VTable} from '@/libs/vue-easytable'
import {regFun} from '@/assets/javascript/common.js';
import Vue from 'vue'
//表格自定义内容组件引入
import {
TableAsc,
TableVisitorName
} from './TableTemplate'
// 自定义列组件
Vue.component('table-cas',TableAsc);
Vue.component('table-visitorname',TableVisitorName);
export default {
name: "Table",
data(){
return {
columns: [],//表头数据
tableData: [],//表数据
tableDataConst:[],//缓存原始表数据 过滤数据使用
dataPage:5,//分页预留
startIndex:1,//拖拽开始索引
endIndex:1,//拖拽结束索引
sortNumber:{},//多列排序:按排列顺序
searchKeyWord:'',//搜索关键字
CAS:['1','2','3']//筛选访客状态
}
},
components:{
VTable
},
methods:{
//多列排序
sortChange(_data){//asc升序 小-》大 & desc降序
console.time('排序计算用时');
let _tableData = this.tableData;
let _key = Object.keys(_data)[0];
console.log(_data[_key]);
_tableData.sort((a,b)=>{
// return (a[_key] > b[_key]);
let A = a[_key],
nA = isNaN(A),
B = b[_key],
nB = isNaN(B);
// 两者皆非number
if(nA && nB){
if (A===""){ return -1;}
if (B===""){ return 1;}
return (A===B?0:A>B?1:-1);
}else if(nA) {
return -1;
}else if(nB) {
return 1;
}else {
return A===B?0:A>B?1:-1;
}
});
if(_data[_key] == 'desc'){
//_tableData = _tableData.reverse();
}
this.tableData = _tableData;
this.tableDataConst = _tableData;
console.timeEnd('排序计算用时');
console.time('排序视图更新用时');
this.$nextTick(function () {
console.timeEnd("排序视图更新用时");
})
//this.tableData[Object.keys(_tableData)]
},
//重新拉取本地数据
getLocationData(_count){
console.time('重新拉取本地数据用时');
let _lData = this.$store.state.tableData;
this.tableData = _lData.tableData.tableData;
console.timeEnd('重新拉取本地数据用时');
this.tableDataConst = _lData.tableData;
console.time('拿到数据后更新视图用时');
this.$nextTick(function () {
console.timeEnd("拿到数据后更新视图用时");
})
},
//重新拉取本地数据
getYAPIData(_count){
console.time('重新拉取mock数据用时');
let _lData = this.$store.state.tableData;
this.tableData = _lData.tableData.tableData;
console.timeEnd('重新拉取mock数据用时');
this.tableDataConst = _lData.tableData;
console.time('重新拉取mock数据后更新视图用时');
this.$nextTick(function () {
console.timeEnd("重新拉取mock数据后更新视图用时");
})
},
//模糊搜索
searchClick(){
},
//行点击回调
rowClick(_index,row,header){
this.$store.commit('visitor/vid',row);
this.bus.$emit('checkVisitor',{msg:'选中了访客',vid:row.ID});
}
},
computed:{
},
watch:{
endIndex(_new,_old){
console.time('拖拽排序用时');
let that = this;
this.columns.splice(_new, 1, ...this.columns.splice(this.startIndex, 1, this.columns[_new]));
this.$nextTick(function () {
console.timeEnd("拖拽排序用时");
})
},
sortNumber(_new){
let _newKeyArr = Object.keys(_new);
this.columns.forEach((op)=>{
_newKeyArr.forEach((item)=>{
if(op.field == item){
op.sortNumber = _new[item];
}
})
})
},
searchKeyWord(_new){
console.time('搜索用时');
let that = this;
this.tableData = this.tableDataConst.filter(data => (!_new ||
data.OperName.toLowerCase().includes(_new.toLowerCase()) ||
data.visitorname.toLowerCase().includes(_new.toLowerCase()) ||
data.Keyword.toLowerCase().includes(_new.toLowerCase()))&&(that.CAS.indexOf(data.CAS.toString() )>-1)
);
this.$nextTick(function () {
console.timeEnd("搜索用时");
})
},
CAS (_new){//类型筛选用时
console.time('类型筛选用时');
//let that = this;
//this.tableData = this.tableDataConst.filter(data => _new === [] || (_new.indexOf(data.CAS.toString() )>-1))
this.$nextTick(function () {
console.timeEnd("类型筛选用时");
})
}
},
filters:{},
async created(){
let that = this;
console.time("头部数据请求用时");
await API.postVisitorList({id:'123',name:'admin'});
let _tableHeader = await API.getTableHeader();
this.columns = _tableHeader.data.tableHeader;
console.timeEnd('头部数据请求用时');
console.time("table数据请求用时");
let _tableBody = await API.getTableBody();//await API.getTableBodyLocal();
this.tableData = _tableBody.tableData;
console.timeEnd('table数据请求用时');
this.tableDataConst = _tableBody.tableData;
/* console.time("table数据筛选用时")
this.tableData = this.tableDataConst.filter(data => that.CAS === [] || (that.CAS.indexOf(data.CAS.toString() )>-1))*/
//console.timeEnd("table数据筛选用时")
console.time('拿到数据后更新视图用时');
this.$nextTick(function () {
console.timeEnd("拿到数据后更新视图用时");
})
},
mounted(){
let domTime = window.performance.timing.domContentLoadedEventEnd - window.performance.timing.navigationStart;
console.log("结构dom渲染时间:"+domTime+"ms");
this.bus.$on('VListSearch',val=>{
this.searchKeyWord = val;
});
this.bus.$on('VListType',val=>{
this.CAS = val;
});
this.bus.$on('checkVisitor',val=>{
console.log(this.$store.state.visitor.data)
})
}
}
</script>
<style lang="scss">
.tablePage{
.searchInput{
border: none;
border-bottom: 2px solid;
position: relative;
top: -2px;
font-size: 12px;
padding: 5px 20px;
}
.cursor-hand{
position: relative;
left: -17px;
}
}
</style>
//vue-easyTable 源码扩展
<td v-for="(col,colIndex) in noFrozenCols"
:class="[col.titleCellClassName]"
ref="vList1"
@mouseup="dragUp($event,col,colIndex)"
@mousemove.stop="handleTitleMouseMove($event,col.field)"
@mousedown.stop.prevent="handleTitleMouseDown($event),dragDown($event,col,colIndex)"
@mouseout.stop="handleTitleMouseOut()"
@click.stop.prevent="titleCellClick(col.field,col.title,col),sortClick($event,col)"
@dblclick.stop="titleCellDblClick(col.field,col.title)">
//data
sortNumber: 0,//当前数字缓存
sortNumberObj: {},//列头字段 + 排序
dragStartX:0,//列头-鼠标按下x
dragStartIndex:0,//列头-鼠标按下x
dragEndX:0,//列头-鼠标抬起x
dragEndIndex:0,//列头-鼠标抬起x
//methods
//表头顺序计数 --操作右侧列表头
sortClick(_el,_col){
console.time('表头计数用时');
if((_col.sortNumber == 0 || typeof _col.sortNumber == 'undefined') && Math.abs(this.dragX.result)<15){
this.sortNumber += 1;
_col.sortNumber = this.sortNumber;
this.$set(this.$parent.sortNumber,_col.field,this.sortNumber)
}
this.$nextTick(function () {
console.timeEnd("表头计数用时");
})
},
//表头拖拽结束--操作右侧列表头
dragUp(_el,_col,_index){
//console.time('拖拽时间')
this.dragEndX = _el.clientX;
this.dragEndIndex = _index;
if(Math.abs(this.dragX.result)>60){
this.$set(this.$parent,'startIndex',this.dragStartIndex);
this.$set(this.$parent,'endIndex',this.dragEndIndex);
}
//console.timeEnd('拖拽时间')
//console.time('拖拽后更新视图用时')
// this.$nextTick(function () {
// console.timeEnd("拖拽后更新视图用时");
// })
},
//表头拖拽开始--操作右侧列表头
dragDown(_el,_col,_index){
this.dragStartX = _el.clientX;
this.dragStartIndex = _index;
}
//表格自定义内容组件js
export const TableAsc = {
template:`<div>
{{rowData.CAS}}<img :src="rowData.cas_img" alt="">
</div>`,
props:{
rowData:{
type:Object
},
field:{
type:String
},
index:{
type:Number
}
}
}
//姓名
export const TableVisitorName = {
template:`<div>
<span class="mgr-5"> {{rowData.visitorname}}</span><img :src="rowData.visitorname_img" alt="">
</div>`,
props:{
rowData:{
type:Object
},
field:{
type:String
},
index:{
type:Number
}
}
}