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 相关文章推荐
在网页里看flash的trace数据的js类
Jan 10 Javascript
Prototype PeriodicalExecuter对象 学习
Jul 19 Javascript
js对象数组按属性快速排序
Jan 31 Javascript
jquery图片轮播插件仿支付宝2013版全屏图片幻灯片
Apr 03 Javascript
IE下通过a实现location.href 获取referer的值
Sep 04 Javascript
jQuery实现浮动层随浏览器滚动条滚动的方法
Sep 22 Javascript
Html5 js实现手风琴效果
Apr 17 Javascript
Node.js中的require.resolve方法使用简介
Apr 23 Javascript
JavaScript你不知道的一些数组方法
Aug 18 Javascript
详解vue中localStorage的使用方法
Nov 22 Javascript
bootstrap-closable-tab可实现关闭的tab标签页插件
Aug 09 Javascript
原生js实现自定义滚动条组件
Jan 20 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+FFMPEG实现将视频自动转码成H264标准Mp4文件
2014/09/24 PHP
PHP发送AT指令实例代码
2016/05/26 PHP
PHP按符号截取字符串的指定部分的实现方法
2018/09/10 PHP
js 方法实现返回多个数据的代码
2009/04/30 Javascript
js+css使DIV始终居于屏幕中间 左下 左上 右上 右下的代码集合
2011/03/10 Javascript
MooBox 基于Mootools的对话框插件
2012/01/20 Javascript
input输入框的自动匹配(原生代码)
2013/03/19 Javascript
JS判断移动端访问设备并加载对应CSS样式
2014/06/13 Javascript
使用jquery 简单实现下拉菜单
2015/01/14 Javascript
jQuery结合ajax实现动态加载文本内容
2015/05/19 Javascript
JavaScript简单修改窗口大小的方法
2015/08/03 Javascript
jquery跟随屏幕滚动效果的实现代码
2016/04/13 Javascript
Javascript对象字面量的理解
2016/06/22 Javascript
ES6概念 Symbol toString()方法
2016/12/25 Javascript
微信小程序 基础组件与导航组件详细介绍
2017/02/21 Javascript
详谈Angular 2+ 的表单(一)之模板驱动型表单
2017/04/25 Javascript
vue数字类型过滤器的示例代码
2017/09/07 Javascript
Vue.js通用应用框架-Nuxt.js的上手教程
2017/12/25 Javascript
layui实现数据表格table分页功能(ajax异步)
2019/07/27 Javascript
微信小程序实现点击空白隐藏的方法示例
2019/08/13 Javascript
详解VUE中的插值( Interpolation)语法
2020/10/18 Javascript
[50:27]OG vs LGD 2018国际邀请赛淘汰赛BO3 第一场 8.26
2018/08/30 DOTA
[36:05]完美世界DOTA2联赛循环赛 Forest vs DM 第一场 11.06
2020/11/06 DOTA
Python实现查找系统盘中需要找的字符
2015/07/14 Python
Django 响应数据response的返回源码详解
2019/08/06 Python
python多线程实现TCP服务端
2019/09/03 Python
OpenCV 之按位运算举例解析
2020/06/19 Python
Pytorch1.5.1版本安装的方法步骤
2020/12/31 Python
CSS3美化表单控件全集
2016/06/29 HTML / CSS
连卡佛中国官网:Lane Crawford中文站
2018/01/27 全球购物
医科大学生的自我评价
2013/12/04 职场文书
校园新闻广播稿
2014/01/10 职场文书
大学学习个人的自我评价
2014/02/18 职场文书
生物学专业求职信
2014/07/23 职场文书
python process模块的使用简介
2021/05/14 Python
Java使用jmeter进行压力测试
2021/07/09 Java/Android