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 相关文章推荐
多个表单中如何获得这个文件上传的网址实现js代码
Mar 25 Javascript
新增加的内容是如何将div的scrollbar自动移动最下面
Jan 02 Javascript
js使用for循环及if语句判断多个一样的name
Sep 09 Javascript
Javascript核心读书有感之词法结构
Feb 01 Javascript
基于jquery实现鼠标滚轮驱动的图片切换效果
Oct 26 Javascript
javascript中加var和不加var的区别 你真的懂吗
Jan 06 Javascript
Jquery技巧(必须掌握)
Mar 16 Javascript
详解webpack 多入口配置
Jun 16 Javascript
Bootstrap实现模态框效果
Sep 30 Javascript
JS异步宏队列微队列原理详解
Sep 09 Javascript
为什么JavaScript中0.1 + 0.2 != 0.3
Dec 03 Javascript
js中Map和Set的用法及区别实例详解
Feb 15 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
重料打造自己的“宝马”---第三代
2021/03/02 无线电
一篇不错的PHP基础学习笔记
2007/03/18 PHP
php中substr()函数参数说明及用法实例
2014/11/15 PHP
php利用cookie实现自动登录的方法
2014/12/10 PHP
JQuery插件fancybox无法在弹出层使用左右键的解决办法
2013/12/25 Javascript
jQuery插件分享之分页插件jqPagination
2014/06/06 Javascript
JS实现IE状态栏文字缩放效果代码
2015/10/24 Javascript
详解jQuery中的empty、remove和detach
2016/04/11 Javascript
Treegrid的动态加载实例代码
2016/04/29 Javascript
jQuery Easyui快速入门教程
2016/08/21 Javascript
AngularJS实现一次监听多个值发生的变化
2016/08/31 Javascript
javascript的document中的动态添加标签实现方法
2016/10/24 Javascript
JS如何设置iOS中微信浏览器的title
2016/11/22 Javascript
详解在vue-cli项目中安装node-sass
2017/06/21 Javascript
信息滚动效果的实例讲解
2017/09/18 Javascript
微信小程序中post方法与get方法的封装
2017/09/26 Javascript
Vue的事件响应式进度条组件实例详解
2018/02/04 Javascript
浅谈FastClick 填坑及源码解析
2018/03/02 Javascript
Angular 利用路由跳转到指定页面的指定位置方法
2018/08/31 Javascript
Node 搭建一个静态资源服务器的实现
2019/05/20 Javascript
[51:11]2014 DOTA2国际邀请赛中国区预选赛5.21 LGD-CDEC VS DT
2014/05/22 DOTA
跟老齐学Python之让人欢喜让人忧的迭代
2014/10/02 Python
Python访问MySQL封装的常用类实例
2014/11/11 Python
Python反射的用法实例分析
2018/02/11 Python
Python识别html主要文本框过程解析
2020/02/18 Python
美国正宗奢华复古手袋、珠宝及配饰网站:What Goes Around Comes Around
2018/07/21 全球购物
澳洲Chemist Direct药房中文网:澳洲大型线上直邮药房
2019/11/04 全球购物
干部现实表现材料
2014/02/13 职场文书
仓库管理员岗位职责
2014/03/19 职场文书
教师党员公开承诺书
2014/03/25 职场文书
煤矿安全知识竞赛活动总结
2014/07/07 职场文书
安全生产一岗双责责任书
2014/07/28 职场文书
党员查摆问题及整改措施
2014/10/10 职场文书
2015年技术员工作总结
2015/04/10 职场文书
教你用Python写一个植物大战僵尸小游戏
2021/04/25 Python
Python四款GUI图形界面库介绍
2022/06/05 Python