//引入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
}
}
}