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 相关文章推荐
JavaScript 私有成员分析
Jan 13 Javascript
javascript中利用数组实现的循环队列代码
Jan 24 Javascript
Javascript中定义方法的另类写法(批量定义js对象的方法)
Feb 25 Javascript
jQuery中not()方法用法实例
Jan 06 Javascript
JS实现带提示的星级评分效果完整实例
Oct 30 Javascript
JS获取文件大小方法小结
Dec 08 Javascript
JavaScript通过代码调用Flash显示的方法
Feb 02 Javascript
基于 Node.js 实现前后端分离
Apr 23 Javascript
JavaScript中的一些隐式转换和总结(推荐)
Dec 22 Javascript
详解Vue源码学习之callHook钩子函数
Jul 25 Javascript
jquery实现手风琴案例
May 04 jQuery
js实现纯前端压缩图片
Nov 16 Javascript
如何在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连接Oracle数据库
2006/10/09 PHP
浅谈PHP接收POST数据方式
2015/06/05 PHP
微信支付PHP SDK ―― 公众号支付代码详解
2016/09/13 PHP
PHP容器类的两种实现方式示例
2019/07/24 PHP
javascript等号运算符使用详解
2015/04/16 Javascript
jQuery检测滚动条是否到达底部
2015/12/15 Javascript
BootStrap初学者对弹出框和进度条的使用感觉
2016/06/27 Javascript
AngularJS之依赖注入模拟实现
2016/08/19 Javascript
解决前端跨域问题方案汇总
2016/11/20 Javascript
在一般处理程序(ashx)中弹出js提示语
2017/08/16 Javascript
JS实现闭包中的沙箱模式示例
2017/09/07 Javascript
jQuery UI 实例讲解 - 日期选择器(Datepicker)
2017/09/18 jQuery
原生JS实现$.param() 函数的方法
2018/08/10 Javascript
react.js组件实现拖拽复制和可排序的示例代码
2018/08/20 Javascript
微信小程序实现同一页面取值的方法分析
2019/04/30 Javascript
20道JS原理题助你面试一臂之力(必看)
2019/07/22 Javascript
vue canvas绘制矩形并解决由clearRec带来的闪屏问题
2019/09/02 Javascript
JavaScript 防抖和节流遇见的奇怪问题及解决
2020/11/20 Javascript
js实现菜单跳转效果
2020/12/11 Javascript
[17:36]VG战队纪录片
2014/08/21 DOTA
[53:20]2018DOTA2亚洲邀请赛 4.1 小组赛 A组加赛 VG vs OG
2018/04/03 DOTA
python 生成不重复的随机数的代码
2011/05/15 Python
浅谈python中copy和deepcopy中的区别
2017/10/23 Python
python编程实现12306的一个小爬虫实例
2017/12/27 Python
Python入门学习指南分享
2018/04/11 Python
Python使用贪婪算法解决问题
2019/10/22 Python
python 怎样进行内存管理
2020/11/10 Python
Pycharm-community-2020.2.3 社区版安装教程图文详解
2020/12/08 Python
金额转换,阿拉伯数字的金额转换成中国传统的形式如:(¥1011)-> (一千零一拾一元整)输出
2015/05/29 面试题
大学生志愿者感言
2014/01/15 职场文书
幼儿园数学教学反思
2014/02/02 职场文书
村主任群众路线个人对照检查材料
2014/09/26 职场文书
2014年社区矫正工作总结
2014/11/18 职场文书
小学副班长竞选稿
2015/11/21 职场文书
2019入党申请书范文3篇
2019/08/21 职场文书
导游词之秦皇岛燕塞湖
2020/01/03 职场文书