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 相关文章推荐
用AJAX返回HTML片段中的JavaScript脚本
Jan 04 Javascript
点击按钮或链接不跳转只刷新页面的脚本整理
Oct 22 Javascript
jquery常用操作小结
Jul 21 Javascript
一款由jquery实现的整屏切换特效
Sep 15 Javascript
node.js中的fs.ftruncate方法使用说明
Dec 15 Javascript
JavaScript中用字面量创建对象介绍
Dec 31 Javascript
jQuery实现的网页左侧在线客服效果代码
Oct 23 Javascript
谈谈js中的prototype及prototype属性解释和常用方法
Nov 25 Javascript
JavaScript实现简单的tab选项卡切换
Jan 05 Javascript
JS IOS/iPhone的Safari浏览器不兼容Javascript中的Date()问题如何解决
Nov 11 Javascript
AngularJS实现的生成随机数与猜数字大小功能示例
Dec 25 Javascript
js实现微信/QQ直接跳转到支付宝APP打开口令领红包功能
Jan 09 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写UltraEdit插件脚本实现方法
2011/12/26 PHP
PHP生成RSS文件类实例
2014/12/05 PHP
php阳历转农历优化版
2016/08/08 PHP
PHP自定义递归函数实现数组转JSON功能【支持GBK编码】
2018/07/17 PHP
javascript getElementsByClassName实现代码
2010/10/11 Javascript
JavaScript arguments 多参传值函数
2010/10/24 Javascript
jQuery拖拽排序插件制作拖拽排序效果(附源码下载)
2016/02/23 Javascript
Angularjs中UI Router的使用方法
2016/05/14 Javascript
深入理解Angular2 模板语法
2016/08/07 Javascript
JS匿名函数类生成方式实例分析
2016/11/26 Javascript
react native带索引的城市列表组件的实例代码
2017/08/08 Javascript
Vue项目全局配置微信分享思路详解
2018/05/04 Javascript
ES6常用小技巧总结【去重、交换、合并、反转、迭代、计算等】
2019/12/21 Javascript
JS实现省市县三级下拉联动
2020/04/10 Javascript
js 解析 JSON 数据简单示例
2020/04/21 Javascript
[41:54]2018DOTA2亚洲邀请赛 4.1 小组赛A组加赛 TNC vs Liquid
2018/04/03 DOTA
Python卸载模块的方法汇总
2016/06/07 Python
全面了解Python环境配置及项目建立
2016/06/30 Python
Python获取当前路径实现代码
2017/05/08 Python
tensorflow使用freeze_graph.py将ckpt转为pb文件的方法
2020/04/22 Python
Selenium webdriver添加cookie实现过程详解
2020/08/12 Python
GUESS Factory加拿大:牛仔裤、服装及配饰
2019/09/20 全球购物
酷瑞网络科技面试题
2012/03/30 面试题
高中生职业生涯规划书
2014/02/24 职场文书
副职竞争上岗演讲稿
2014/05/12 职场文书
平安家庭示范户事迹
2014/06/02 职场文书
弘扬焦裕禄精神走群众路线思想汇报
2014/09/12 职场文书
2014党员干部四风问题对照检查材料思想汇报
2014/09/24 职场文书
卫校毕业生自我鉴定
2014/09/28 职场文书
地球上的星星观后感
2015/06/02 职场文书
居安思危观后感
2015/06/11 职场文书
2016圣诞节贺卡寄语
2015/12/07 职场文书
redis 限制内存使用大小的实现
2021/05/08 Redis
Python带你从浅入深探究Tuple(基础篇)
2021/05/15 Python
Redis模仿手机验证码发送的实现示例
2021/11/02 Redis
一起来学习Python的元组和列表
2022/03/13 Python