Vue自定义指令实现checkbox全选功能的方法


Posted in Javascript onFebruary 28, 2018

最近做的一个项目需要用到Vue实现全选功能,参考了一下网上的做法,发现用属性计算的复用性不高,于是选用自定义指令,但网上的做法大多是会对原始数据有一定的格式要求,而且没有返回结果,于是做了改进。

上代码:

<!DOCTYPE html>
<html>
 <head>
  <meta charset="UTF-8">
  <title></title>
 </head>
 <body>
  <div id="app">
  <input type="checkbox" v-model="allCheck" v-check-all="allCheck" check-data="list" result="customerResult" key="demo"> 全选
  <ul> 
   <li v-for="item in list"> 
    <input type="checkbox" v-model="item.checked"> 
    {{item.demo}}
   </li> 
  </ul> 
  <div >
   customerResult: {{customerResult}}
  </div>
  </div>
  <script src="vue.js"></script>
  <script>
   var vm = new Vue({
    el: "#app",
    data:function(){
     return {
      list:[{demo:1},
      {demo:2},
      {demo:3}],
      allCheck:'',
      customerResult:'',
     }
    },
    directives: {
     'check-all': {
      twoWay: true,
      params: ['checkData','result','key'],
      bind() {
       /*为原始数据的每一个对象添加一个checked属性*/
       this.vm[this.params.checkData].forEach((item)=>{
        Vue.set(item,'checked',false)
       });
       /*提取被选中的项*/
       this.setValue=function(){
        let result=[]
        this.vm[this.params.checkData].forEach((item) => {
         if(item.checked){
          result.push(item[this.params.key])
         }
        });
        this.vm[this.params.result]=result
       }
        /*如果所有的列表的checked属性都为true,则选中全选框,否则不选中全选框 */
       this.vm.$watch(this.params.checkData, (data) => {
        if(data.every((item) => item.checked)) {
         this.set(true);
        } else {
         this.set(false);
        }
        this.setValue()
       }, {deep: true});
      },
      // checkAll发生更改时 
      update(checkAll) {
        /*如果全选框被选中,则将列表的所有checked属性转为true,否则转为false */
       if(checkAll) {
        this.vm[this.params.checkData].forEach((item) => {
         item.checked = true;
        });
       } else {
        this.vm[this.params.checkData].forEach((item) => {
         item.checked = false;
        });
       }
       this.setValue()
      },
     },
    }
   })
  </script>
 </body>
</html>

通常我们都要获取原始数据中的某个键值,可在“key”中填进想要获取的键值,“result”就是被选中的项了。
有时,我们需要返回一个完整的对象修改一下代码,当不输入key时,返回一个完整的对象数组

this.setValue=()=>{
 let result=[]
 this.vm[this.params.checkData].forEach((item) => {
  //删除checked属性
  let temp={};
  (()=>delete Object.assign(temp,item).checked)();
  item.checked?result.push(item[this.params.key]||temp):"";
 });
 this.vm[this.params.result]=result
}

但时,这时,返回来的数组中对象中并没有与与原数据是相同的引用地址,当需要使用array.$remove()函数时就会失败,新增一个relative参数,用户自定义判断返回的数据是否与原始数据关联

this.setValue = () => {
 let result = []
 this.vm[this.params.checkData].forEach((item) => {
  if(this.params.relative) {
   item.checked ? result.push(item) : "";
  }else{
   //删除checked属性
   let temp = {};
   (() => delete Object.assign(temp, item).checked)();
   item.checked ? result.push(item[this.params.key] || temp) : "";
  }
 });
 this.vm[this.params.result] = result
}

当数据长度大于2个时,需要判断2N次,相当消耗性能,优化一下:

'check-all', {
  twoWay: true,
  params: ['checkData', 'result', 'key','relative'],
  /*checkData:列表数据,
  result:返回的结果,
  key:列表数据中需要返回的字段,
  relative:是否返回与列表数据相同引用地址的选中结果*/
  bind() {
   /*提取被选中的项*/
  this.setValue = () => {
   let result = []
   if (this.params.relative) {
    this.vm[this.params.checkData].forEach((item) => {
     item.checked ? result.push(item) : "";
    });
   } else {
    this.vm[this.params.checkData].forEach((item) => {
     //删除checked属性
     let temp = {};
     (() => delete Object.assign(temp, item).checked)();
     item.checked ? result.push(item[this.params.key] || temp) : "";
    });
   }
   this.vm[this.params.result] = result
  };
   /*为原始数据的每一个对象添加一个checked属性*/
  this.addChecked = () => {
   this.vm[this.params.checkData].forEach((item) => {
    Vue.set(item, 'checked', false)
   });
  };
  /*如果所有的列表的checked属性都为true,则选中全选框,否则不选中全选框 */
  this.vm.$watch(this.params.checkData, (data) => {
   if(!data.length) return;
   data.every((item) => item.checked) ? this.set(true) : this.set(false);
   this.setValue()
  }, {deep: true});
  //当列表发生变化时重新绑定
  this.vm.$watch(this.params.checkData, (data) => {
   if(!data.length) return
   this.addChecked();
  });
  },
  // checkAll发生更改时 
  update(checkAll) {
   /*如果全选框被选中,则将列表的所有checked属性转为true,否则转为false */
   checkAll ? this.vm[this.params.checkData].forEach((item) => {
    item.checked = true
   }) : this.vm[this.params.checkData].forEach((item) => {
    item.checked = false
   });
   this.setValue()
  },
 }

这时只需要判断N+1次。

以上这篇Vue自定义指令实现checkbox全选功能的方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jquery遍历table的tr获取td的值实现方法
May 19 Javascript
JS模拟bootstrap下拉菜单效果实例
Jun 17 Javascript
JavaScript直播评论发弹幕切图功能点集合效果代码
Jun 26 Javascript
jQuery 特性操作详解及实例代码
Sep 29 Javascript
js模糊查询实例分享
Dec 26 Javascript
AngularJS获取json数据的方法详解
May 27 Javascript
Node.js 使用命令行工具检查更新
Jun 08 Javascript
基于LayUI实现前端分页功能的方法
Jul 22 Javascript
基于vue.js路由参数的实例讲解——简单易懂
Sep 07 Javascript
electron demo项目npm install安装失败的解决方法
Feb 06 Javascript
微信小程序拼接图片链接无底洞深入探究
Sep 03 Javascript
利用Vue实现简易播放器的完整代码
Dec 30 Vue.js
如何在vue中使用ts的示例代码
Feb 28 #Javascript
angularjs select 赋值 ng-options配置方法
Feb 28 #Javascript
select获取下拉框的值 下拉框默认选中方法
Feb 28 #Javascript
AngularJS select加载数据选中默认值的方法
Feb 28 #Javascript
基于vue-cli vue-router搭建底部导航栏移动前端项目
Feb 28 #Javascript
Vue-Router模式和钩子的用法
Feb 28 #Javascript
angularjs 获取默认选中的单选按钮的value方法
Feb 28 #Javascript
You might like
Php做的端口嗅探器--可以指定网站和端口
2006/10/09 PHP
TMDPHP 模板引擎使用教程
2012/03/13 PHP
php上传图片到指定位置路径保存到数据库的具体实现
2013/12/30 PHP
php实现多维数组中每个单元值(数字)翻倍的方法
2015/02/16 PHP
如何离线执行php任务
2017/02/21 PHP
PHP控制反转(IOC)和依赖注入(DI)
2017/03/13 PHP
img onload事件绑定各浏览器均可执行
2012/12/19 Javascript
JavaScript中使用Substring删除字符串最后一个字符
2013/11/03 Javascript
jQuery探测位置的提示弹窗(toolTip box)详细解析
2013/11/14 Javascript
jquery控制页面部分刷新的方法
2015/06/24 Javascript
使用jQuery mobile库检测url绝对地址和相对地址的方法
2015/12/04 Javascript
Angular 4.x 路由快速入门学习
2017/05/03 Javascript
JS判断一个数是否是水仙花数
2017/06/11 Javascript
js实现首屏延迟加载实现方法 js实现多屏单张图片延迟加载效果
2017/07/17 Javascript
layui的table中显示图片方法
2018/08/17 Javascript
JavaScript装饰者模式原理与用法实例详解
2020/03/09 Javascript
[02:20]DOTA2中文配音宣传片
2013/05/22 DOTA
Python处理RSS、ATOM模块FEEDPARSER介绍
2015/02/18 Python
浅析Python3中的对象垃圾收集机制
2019/06/06 Python
python替换字符串中的子串图文步骤
2019/06/19 Python
Python转换时间的图文方法
2019/07/01 Python
基于Python的ModbusTCP客户端实现详解
2019/07/13 Python
python实现批量修改服务器密码的方法
2019/08/13 Python
Python中Qslider控件实操详解
2021/02/20 Python
波兰香水和化妆品购物网站:Notino.pl
2017/11/07 全球购物
Guess美国官网:美国知名服装品牌
2019/04/08 全球购物
学校安全检查制度
2014/01/27 职场文书
社区安全检查制度
2014/02/03 职场文书
求职信模板
2014/05/23 职场文书
2015年图书馆个人工作总结
2015/05/26 职场文书
董事长助理工作总结2015
2015/07/23 职场文书
2019XX公司员工考核管理制度!
2019/08/07 职场文书
MySQL Router的安装部署
2021/04/24 MySQL
Python数据可视化之用Matplotlib绘制常用图形
2021/06/03 Python
Java如何实现通过键盘输入一个数组
2022/02/15 Java/Android
MYSQL事务的隔离级别与MVCC
2022/05/25 MySQL