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 相关文章推荐
JSQL 基于客户端的成绩统计实现方法
May 05 Javascript
一个轻量级的javascript库 pj介绍
Dec 19 Javascript
jQuery插件Elastislide实现响应式的焦点图无缝滚动切换特效
Apr 12 Javascript
js仿淘宝和百度文库的评分功能
May 15 Javascript
JavaScript中解决多浏览器兼容性23个问题的快速解决方法
May 19 Javascript
JS HTML5实现拖拽移动列表效果
Aug 27 Javascript
使用Browserify来实现CommonJS的浏览器加载方法
May 14 Javascript
AngularJS select设置默认值的实现方法
Aug 25 Javascript
基于vue开发的在线付费课程应用过程
Jan 25 Javascript
javascript简单实现深浅拷贝过程详解
Oct 08 Javascript
在vue中使用axios实现post方式获取二进制流下载文件(实例代码)
Dec 16 Javascript
JavaScript代码压缩工具UglifyJS和Google Closure Compiler的基本用法
Apr 13 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 session_set_save_handler 函数的用法(mysql)
2013/06/29 PHP
浅谈PHP值mysql操作类
2016/06/29 PHP
php倒计时出现-0情况的解决方法
2016/07/28 PHP
php版微信发红包接口用法示例
2016/09/23 PHP
PHP对象链式操作实现原理分析
2016/10/09 PHP
php 解析xml 的四种方法详细介绍
2016/10/26 PHP
javascript addBookmark 加入收藏 多浏览器兼容
2009/08/15 Javascript
Prototype源码浅析 String部分(二)
2012/01/16 Javascript
js或者jquery判断图片是否加载完成实现代码
2013/03/20 Javascript
jquery获取tr中控件值并操作tr实现思路
2013/03/27 Javascript
使用JQ来编写最基本的淡入淡出效果附演示动画
2014/10/31 Javascript
JavaScript Math.floor方法(对数值向下取整)
2015/01/09 Javascript
原生javascript实现addClass,removeClass,hasClass函数
2016/02/25 Javascript
javascript与jquery动态创建html元素示例
2016/07/25 Javascript
利用Angularjs和Bootstrap前端开发案例实战
2016/08/27 Javascript
jQuery实现立体式数字动态增加(animate方法)
2016/12/21 Javascript
jQuery简单获取DIV和A标签元素位置的方法
2017/02/07 Javascript
原生js和css实现图片轮播效果
2017/02/07 Javascript
微信小程序 弹窗自定义实例代码
2017/03/08 Javascript
详解JavaScript中的坐标和距离
2019/05/27 Javascript
layui中的switch开关实现方法
2019/09/03 Javascript
layer插件实现在弹出层中弹出一警告提示并关闭弹出层的方法
2019/09/24 Javascript
如何实现iframe父子传参通信
2020/02/05 Javascript
vant 中van-list的用法说明
2020/11/11 Javascript
pygame学习笔记(3):运动速率、时间、事件、文字
2015/04/15 Python
Kears+Opencv实现简单人脸识别
2019/08/28 Python
Myprotein意大利官网:欧洲第一运动营养品牌
2018/11/22 全球购物
违反课堂纪律检讨书
2014/01/19 职场文书
物理力学求职信
2014/02/18 职场文书
学校招生宣传广告词
2014/03/19 职场文书
毕业生自荐信如何写
2014/03/24 职场文书
办理收楼委托书范本
2014/10/09 职场文书
倡议书作文
2015/01/19 职场文书
2015年信息中心工作总结
2015/05/25 职场文书
Redis安装启动及常见数据类型
2021/04/14 Redis
浅谈css清除浮动(clearfix和clear)的用法
2023/05/21 HTML / CSS