本文实例讲述了vue2.0结合DataTable插件实现表格动态刷新的方法。分享给大家供大家参考,具体如下:
产品提出的需求是这样的,很普通的一个统计server端task完成率和状态的表格,要自动刷新其中的数据,并且当单个task完成的时候report给server端,看起来好easy好easy的一个需求啊!且听我说完哈!
我这边使用的是框架是vue,表格自然用v-for渲染,然后我们这边分页搜索神马的都是前端弄,也就是说后端只管把一大坨数据塞到前端,然后前端自己组装分页器和完成模糊搜索,所以啊,我之前用的是DataTable这个插件,组装好的表格效果如下,看着没毛病哈!

可是涉及到自动刷新就有问题了,因为每次获取数据都是全量数据,用dataTable组装表格的话,就必须要组装好的表格destroy掉,然后再v-for再DataTable()组装..页面会一直一直闪!体验好差的说!
我只想出了一个比较笨的方法解决这个局部刷新的问题,大家要是有更好的方法一定要告诉我!!上代码!
1.v-for只渲染不变的数据,比如名字备注之类的,一直刷新的字段比如状态和完成率都为空,就这样,只用DataTable首次渲染表格
2.setRefresh是一个定时器,每隔1s就递归调用一次自己,query全量数据,存放到originTableList里
3.updateRefreshStatus是用原生的js去获取每行的dom,然后innerText去改变其值
4.reportTaskComplete是当当前这个task完成率达到100%就汇报给server
5.checkTaskRefresh是递归检查所有的任务,把完成的任务放到completeTaskList,如果全都完成了就把定时器清除掉
6.beforeRouteLeave是vue router的方法,在离开路由之后清除计时器
template
<template>
<div class="row">
<loadingHourGlass></loadingHourGlass>
<div class="col-xs-12 top-offset-15 bottom-offset-15">
<div>
<strong class="pull-left line-height-24 right-offset-15">自动刷新开关:</strong>
<iphoneSwitcher v-bind:status="refresh.status" v-bind:canSwitch="false" v-bind:callBackName="'switchRefreshStatus'"></iphoneSwitcher>
</div>
<button type="button" class="btn btn-sm btn-primary pull-right" v-on:click="editRecord()">添加任务</button>
</div>
<div class="col-xs-12 main-table-wrapper">
<h4 class="page-header">点播刷新任务数据表格 <!-- <small>Secondary text</small> --></h4>
<!-- <p>123</p> -->
<table class="table table-striped table-hover table-bordered" id="main-table">
<thead>
<tr>
<th>名称</th>
<th>状态</th>
<th>完成率</th>
<th>创建时间</th>
<th>备注</th>
<th>操作</th>
</tr>
</thead>
<tbody><!-- v-bind:class=" (item.completeCount/item.total=='1')?'text-success':'text-danger' " -->
<tr v-for="item in tableList" v-bind:class="'id-' + item.id">
<td>{{ item.file_name }}</td>
<!-- {{ item.status | statusFilter }} -->
<td class="status"></td>
<!-- v-bind:class=" (item.completeCount/item.total=='1')?'text-success':'text-danger' " -->
<!-- {{ item.completeRate }} -->
<td class="rate"></td>
<td>{{ item.create_time }}</td>
<td>{{ item.description }}</td>
<td>
<button type="button" class="btn btn-primary btn-xs" v-on:click="showDetailModal(item.id,item.file_name)">详情</button>
<!-- <button type="button" class="btn btn-danger btn-xs" v-on:click="test()">test</button> -->
</td>
</tr>
</tbody>
</table>
</div>
</div>
</template>
</div>
js
methods: {
initRecordTable: function(){
$('#main-table').DataTable({
"paging": true,// 开启分页
"pageLength": 10,//每页显示数量
"lengthChange": true,//是否允许用户改变表格每页显示的记录数
"searching": true,//搜索
"ordering": true,//排序
"info": true,//左下角 从 1 到 5 /共 23 条数据
"autoWidth": true,
// "scrollX": "100%",//表格的宽度
// "scrollY": "200px",//表格的高度
"scrollXInner": "100%",//表格的内容宽度
// "bScrollCollapse":true,//当显示的数据不足以支撑表格的默认的高度时,依然显示纵向的滚动条。(默认是false)
"aaSorting": [
[3, 'asc']
],
"language": {
"sInfoEmpty": "没有数据",
"sZeroRecords": "没有查找到满足条件的数据",
"sInfo": "从 _START_ 到 _END_ /共 _TOTAL_ 条数据",
"sLengthMenu": "每页显示 _MENU_ 条记录",
"sInfoFiltered": "(从 _MAX_ 条数据中检索)",
"oPaginate": {
"sFirst": "首页",
"sPrevious": "前一页",
"sNext": "后一页",
"sLast": "尾页"
}
},
});
},
initQuery: function(){
// status 和 rate两个字段是实时刷新的
// dataTable摧毁和tableList赋值都砸在promise里完成
// tableList只初始化的时候赋值一次 然后就不动了 用原生js去改变表格内的status字段
let mySelf = this;
let callback = function(){
if($('#main-table').DataTable()){
$('#main-table').DataTable().destroy()
}
mySelf.tableList = util.deepClone(mySelf.originTableList);
}
let queryTablePromise = mySelf.queryTable(callback);
let promiseList = [];
mySelf.clearRefresh();
promiseList.push(queryTablePromise);
Promise.all(promiseList).then(function (result) {
console.log('ajax全部执行完毕:' + JSON.stringify(result)); // ["Hello", "World"]
//renderTable函数只在首次进入页面时调用 1.毁掉dataTable插件 2.加载一次表格更新状态和完成率 3.调用自动刷新
mySelf.renderTable();
mySelf.updateRefreshStatus();
mySelf.setRefresh();
});
},
switchRefreshStatus: function(){
let mySelf = this;
let status = mySelf.refresh.status;
let text = (status==true)?'关闭':'开启';
let confirmCallback = null;
if (status==true){
confirmCallback = function(){
mySelf.refresh.status = false;
}
}
else{
confirmCallback = function(){
mySelf.refresh.status = true;
mySelf.setRefresh();
}
}
util.showConfirm('确认要' + text + '自动刷新么?',confirmCallback);
},
checkTaskRefresh: function(){
let mySelf = this;
let originTableList = mySelf.originTableList;
let taskAllComplete = true;
// console.log(JSON.stringify(mySelf.originTableList));
originTableList.forEach(function(item,index,array){
let completeTaskList = mySelf.refresh.completeTaskList;
let completeRate = item.completeRate;
//当前task完成 report给后端
if (Number.parseInt(completeRate) == 1){
// 若任务完成列表 没有这个TaskId 则发送请求
if (!completeTaskList.includes(item.id)){
console.log(item.id + "任务完成了!并且不存在于任务完成列表,现在发送完成请求!");
mySelf.reportTaskComplete(item.id);
mySelf.refresh.completeTaskList.push(item.id);
}
}
else{
taskAllComplete = false;
}
});
if(taskAllComplete){
console.log('全部任务都完成了!')
return true;
}
return false;
},
setRefresh: function(){
let mySelf = this;
let status = mySelf.refresh.status;
let interval = mySelf.refresh.interval;
// 如果所有任务都完成了 则停止发送ajax请求 并更新最后一次
if (mySelf.checkTaskRefresh()){
console.log('更新最后一次表格!')
mySelf.updateRefreshStatus();
return false;
}
// console.log('refresh')

