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实现心算练习代码
Dec 06 Javascript
数组方法解决JS字符串连接性能问题有争议
Jan 12 Javascript
基于jquery点击自以外任意处,关闭自身的代码
Feb 10 Javascript
Jquery index()方法 获取相应元素索引值
Oct 12 Javascript
JS弹出窗口代码大全(详细整理)
Dec 21 Javascript
js判断undefined类型,undefined,null, 的区别详细解析
Dec 16 Javascript
JavaScript中对象property的读取和写入方法介绍
Dec 30 Javascript
jQuery实现字符串全部替换的方法【推荐】
Mar 09 Javascript
详解从angular-cli:1.0.0-beta.28.3升级到@angular/cli:1.0.0
May 22 Javascript
Angularjs 实现动态添加控件功能
May 25 Javascript
JS获取数组中出现次数最多及第二多元素的方法
Oct 27 Javascript
JS实现鼠标移动拖尾
Dec 27 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
ThinkPHP添加更新标签的方法
2014/12/05 PHP
Yii中srbac权限扩展模块工作原理与用法分析
2016/07/14 PHP
利用onresize使得div可以随着屏幕大小而自适应的代码
2010/01/15 Javascript
非html5实现js版弹球游戏示例代码
2013/09/22 Javascript
jQuery 1.9.1源码分析系列(十五)之动画处理
2015/12/03 Javascript
快速解决jquery.touchSwipe左右滑动和垂直滚动条冲突
2016/04/15 Javascript
谈谈Vue.js——vue-resource全攻略
2017/01/16 Javascript
vue计算属性及使用详解
2018/04/02 Javascript
如何编写一个d.ts文件的步骤详解
2018/04/13 Javascript
加快Vue项目的开发速度的方法
2018/12/12 Javascript
详解 微信小程序开发框架(MINA)
2019/05/17 Javascript
Vue初始化中的选项合并之initInternalComponent详解
2020/06/11 Javascript
JavaScript Image对象实现原理实例解析
2020/08/26 Javascript
element-ui tree结构实现增删改自定义功能代码
2020/08/31 Javascript
[57:53]DOTA2上海特级锦标赛主赛事日 - 2 败者组第二轮#3OG VS VP
2016/03/03 DOTA
Python中条件选择和循环语句使用方法介绍
2013/03/13 Python
python 数据的清理行为实例详解
2017/07/12 Python
python 实现一个贴吧图片爬虫的示例
2017/10/12 Python
利用Python暴力破解zip文件口令的方法详解
2017/12/21 Python
Python3.6连接Oracle数据库的方法详解
2018/05/18 Python
Sanic框架流式传输操作示例
2018/07/18 Python
Python3中内置类型bytes和str用法及byte和string之间各种编码转换 问题
2018/09/27 Python
Python实现简易过滤删除数字的方法小结
2019/01/09 Python
详解python 模拟豆瓣登录(豆瓣6.0)
2019/04/18 Python
Python中的X[:,0]、X[:,1]、X[:,:,0]、X[:,:,1]、X[:,m:n]和X[:,:,m:n]
2020/02/13 Python
Python实现AI自动抠图实例解析
2020/03/05 Python
Python基于codecs模块实现文件读写案例解析
2020/05/11 Python
在tensorflow以及keras安装目录查询操作(windows下)
2020/06/19 Python
python中altair可视化库实例用法
2021/01/26 Python
澳大利亚旅游网站:Lastminute
2017/08/07 全球购物
关于Java String的一道面试题
2013/09/29 面试题
大学生军训自我评价分享
2013/11/09 职场文书
新学期教师寄语
2014/04/02 职场文书
爱祖国演讲稿
2014/05/04 职场文书
2015年学校教科室工作总结
2015/07/20 职场文书
MySQL外键约束(FOREIGN KEY)案例讲解
2021/08/23 MySQL