vue2.0结合DataTable插件实现表格动态刷新的方法详解


Posted in Javascript onMarch 17, 2017

本文实例讲述了vue2.0结合DataTable插件实现表格动态刷新的方法。分享给大家供大家参考,具体如下:

产品提出的需求是这样的,很普通的一个统计server端task完成率和状态的表格,要自动刷新其中的数据,并且当单个task完成的时候report给server端,看起来好easy好easy的一个需求啊!且听我说完哈!

我这边使用的是框架是vue,表格自然用v-for渲染,然后我们这边分页搜索神马的都是前端弄,也就是说后端只管把一大坨数据塞到前端,然后前端自己组装分页器和完成模糊搜索,所以啊,我之前用的是DataTable这个插件,组装好的表格效果如下,看着没毛病哈!

vue2.0结合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>

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')
    if (status){
      mySelf.refresh.timer = setTimeout(function(){
        let queryTablePromise = mySelf.queryTable();
        let promiseList = [];
        promiseList.push(queryTablePromise);
        Promise.all(promiseList).then(function (result) {
          console.log('ajax全部执行完毕:' + JSON.stringify(result)); // ["Hello", "World"]
          mySelf.updateRefreshStatus();
          mySelf.setRefresh();
        });
      },interval);
    }
    else{
      mySelf.clearRefresh();
    }
  },
  updateRefreshStatus: function(){
    console.log('更新刷新状态')
    let mySelf = this;
    let mainTable = document.getElementById("main-table");
    let originTableList = mySelf.originTableList;
    originTableList.forEach(function(item,index,array){
      let trClassName = "id-" + item.id;
      // console.log(trClassName)
      // 获取当前页面展示的所有tr
      let trDom = mainTable.getElementsByClassName(trClassName)[0];
      // console.log(trDom)
      // 局部刷新个别字段
      if (trDom){
        let tdRate = trDom.getElementsByClassName("rate")[0];
        let tdStatus = trDom.getElementsByClassName("status")[0];
        tdRate.innerText = item.completeRate;
        tdRate.className = (item.status == "1")?"text-info rate":((item.status == "2")?"text-success rate":"text-danger rate");
        tdStatus.innerText = (item.status == "1")?"刷新中":((item.status == "2")?"刷新完成":"刷新失败");
        tdStatus.className = (item.status == "1")?"text-info status":((item.status == "2")?"text-success status":"text-danger status");
      }
    });
  },
  clearRefresh: function(){
    let mySelf = this;
    console.log('clear timer');
    clearTimeout(mySelf.refresh.timer);
  },
  queryTable: function(callback){
    let mySelf = this;
    let promise = new Promise(function (resolve, reject) {
      let url = pars.domain + "/api.php?Action=xxxxxxx&t=" + (new Date).getTime();
      $.get(url, function(res) {
        if (res.code == 0) {
          let resData = res.list;
          resData.forEach(function(item,index,array){
            let info = item.info;
            let completeCount = info.completeCount;
            let total = info.count;
            item.completeRate = ((completeCount/total)*100).toFixed(2) + "%";
          });
          // console.log(JSON.stringify(resData))
          mySelf.originTableList = resData;
          if (callback){
            callback();
          }
          resolve('queryTable完成!');
        }
        else{
          util.showDialog('error',"接口调用失败,报错信息为:" + res.message);
        }
      }, "json");
    });
    return promise;
  },
  renderTable: function(){
    let mySelf = this;
    mySelf.$nextTick(function(){
      mySelf.initRecordTable();
      util.hideLoading();
    })
  }
},
beforeRouteLeave (to, from, next){
  let mySelf = this;
  mySelf.clearRefresh();
  next();
},

整体的效果如下,功能整体是实现了,但是感觉好笨的说,大家要是有好办法一定要告诉我哈!!

vue2.0结合DataTable插件实现表格动态刷新的方法详解

希望本文所述对大家vue.js程序设计有所帮助。

Javascript 相关文章推荐
用正则xmlHttp实现的偷(转)
Jan 22 Javascript
关于javascript中的parseInt使用技巧
Sep 03 Javascript
JavaScript CSS修改学习第五章 给“上传”添加样式
Feb 19 Javascript
DWZ table的原生分页浅谈
Mar 01 Javascript
解析Javascript中难以理解的11个问题
Dec 09 Javascript
Javascript实现的常用算法(如冒泡、快速、鸽巢、奇偶等)
Apr 29 Javascript
jQuery中:checked选择器用法实例
Jan 04 Javascript
微信小程序 教程之数据绑定
Oct 18 Javascript
小程序ios音频播放没声音问题的解决
Jul 11 Javascript
vue将毫秒数转化为正常日期格式的实例
Sep 16 Javascript
js/jquery遍历对象和数组的方法分析【forEach,map与each方法】
Feb 27 jQuery
jquery实现简单拖拽效果
Jul 20 jQuery
AngularJS路由切换实现方法分析
Mar 17 #Javascript
js判断是否是手机页面
Mar 17 #Javascript
Angular组件化管理实现方法分析
Mar 17 #Javascript
Bootstrap表单制作代码
Mar 17 #Javascript
Bootstrap 过渡效果Transition 模态框(Modal)
Mar 17 #Javascript
使用vue.js编写蓝色拼图小游戏
Mar 17 #Javascript
Vue.js实现一个漂亮、灵活、可复用的提示组件示例
Mar 17 #Javascript
You might like
PHP写的资源下载防盗链类分享
2014/05/12 PHP
PHP中UNIX时间戳和日期间的转换与计算实例
2014/11/19 PHP
php微信公众平台交互与接口详解
2016/11/28 PHP
php设计模式之单例模式用法经典示例分析
2019/09/20 PHP
js实现拉伸拖动iframe的具体代码
2013/08/03 Javascript
jQuery实现的支持IE的html滑动条
2015/03/16 Javascript
js闭包实现按秒计数
2015/04/23 Javascript
Bootstrap每天必学之响应式导航、轮播图
2016/04/25 Javascript
JavaScript的事件机制详解
2017/01/17 Javascript
JS中setTimeout和setInterval的最大延时值详解
2017/02/13 Javascript
Boostrap栅格系统与自己额外定义的媒体查询的冲突问题
2017/02/19 Javascript
如何编写jquery插件
2017/03/29 jQuery
Avalonjs双向数据绑定与监听的实例代码
2017/06/23 Javascript
vuejs父子组件之间数据交互详解
2017/08/09 Javascript
微信页面弹出键盘后iframe内容变空白的解决方案
2017/09/20 Javascript
ES6 javascript中class类的get与set用法实例分析
2017/10/30 Javascript
Java设计中的Builder模式的介绍
2018/03/22 Javascript
深入Vue-Router路由嵌套理解
2018/08/13 Javascript
layUI实现三级导航菜单效果
2019/07/26 Javascript
使用layui的layer组件做弹出层的例子
2019/09/27 Javascript
基于Vue中使用节流Lodash throttle详解
2019/10/30 Javascript
Python中使用HTMLParser解析html实例
2015/02/08 Python
Python 实现链表实例代码
2017/04/07 Python
Pycharm学习教程(2) 代码风格
2017/05/02 Python
python数字图像处理之高级滤波代码详解
2017/11/23 Python
Python键盘输入转换为列表的实例
2018/06/23 Python
python实现傅里叶级数展开的实现
2018/07/21 Python
Python编程flask使用页面模版的方法
2018/12/28 Python
python实现身份证实名认证的方法实例
2019/11/08 Python
Python3基本输入与输出操作实例分析
2020/02/14 Python
python GUI库图形界面开发之PyQt5单行文本框控件QLineEdit详细使用方法与实例
2020/02/27 Python
监理员的岗位职责
2013/11/13 职场文书
2014年禁毒工作总结
2014/11/24 职场文书
世界遗产导游词
2015/02/13 职场文书
幼儿园园长工作总结2015
2015/05/25 职场文书
Windows中Redis安装配置流程并实现远程访问功能
2021/06/07 Redis