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 相关文章推荐
用Mootools获得操作索引的两种方法分享
Dec 12 Javascript
js实现页面转发功能示例代码
Aug 05 Javascript
jquery全选checkBox功能实现代码(取消全选功能)
Dec 10 Javascript
javascript处理a标签超链接默认事件的方法
Jun 29 Javascript
javascript定义类和类的实现实例详解
Dec 01 Javascript
简单的JS时钟实例讲解
Jan 13 Javascript
JS实现消息来时让网页标题闪动效果的方法
Apr 20 Javascript
浅谈DOM的操作以及性能优化问题-重绘重排
Jan 08 Javascript
解决vue中对象属性改变视图不更新的问题
Feb 23 Javascript
浅谈React组件之性能优化
Mar 02 Javascript
laydate时间日历插件使用方法详解
Nov 14 Javascript
JavaScript Window浏览器对象模型原理解析
May 30 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中的include、include_once、require以及require_once语句
2016/04/23 PHP
PHP的curl函数的用法总结
2019/02/14 PHP
PHP+MySql实现一个简单的留言板
2020/07/19 PHP
Js callBack 返回前一页的js方法
2008/11/30 Javascript
javascript与asp.net(c#)互相调用方法
2009/12/13 Javascript
批量实现面向对象的实例代码
2013/07/01 Javascript
使用upstart把nodejs应用封装为系统服务实例
2014/06/01 NodeJs
jquery mobile 移动web(5)
2015/12/20 Javascript
JS创建对象几种不同方法详解
2016/03/01 Javascript
有趣的bootstrap走动进度条
2016/12/01 Javascript
angular实现IM聊天图片发送实例
2017/05/08 Javascript
angularjs实现上拉加载和下拉刷新数据功能
2017/06/12 Javascript
JavaScript中in和hasOwnProperty区别详解
2017/08/04 Javascript
JavaScript实现重力下落与弹性效果的方法分析
2017/12/20 Javascript
React key值的作用和使用详解
2018/08/23 Javascript
es6数值的扩展方法
2019/03/11 Javascript
json解析大全 双引号、键值对不在一起的情况
2019/12/06 Javascript
JS如何实现手机端输入验证码效果
2020/05/13 Javascript
vue - props 声明数组和对象操作
2020/07/30 Javascript
分析Python的Django框架的运行方式及处理流程
2015/04/08 Python
Python的string模块中的Template类字符串模板用法
2016/06/27 Python
利用pyinstaller或virtualenv将python程序打包详解
2017/03/22 Python
Python中的命令行参数解析工具之docopt详解
2017/03/27 Python
Python深度优先算法生成迷宫
2018/01/22 Python
python如何调用java类
2020/07/05 Python
Python实现壁纸下载与轮换
2020/10/19 Python
让IE支持CSS3的不完全兼容方案
2014/09/19 HTML / CSS
CSS3 animation ? steps 函数详解
2019/08/30 HTML / CSS
美国单身专业人士在线约会网站:EliteSingles
2019/03/19 全球购物
测试驱动开发的主要步骤是什么
2014/12/10 面试题
AssertionError 跟一下那个类是 “is – a”的关系
2012/02/21 面试题
护士自我评价
2014/02/01 职场文书
《夹竹桃》教学反思
2014/04/20 职场文书
学校开学标语
2014/10/06 职场文书
推荐信范文大全
2015/03/27 职场文书
使用pipenv管理python虚拟环境的全过程
2021/09/25 Python