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.mousewheel实现整屏翻屏效果
Aug 30 Javascript
使用JavaScript和CSS实现文本隔行换色的方法
Nov 04 Javascript
jQuery自动完成插件completer附源码下载
Jan 04 Javascript
js实现的页面矩阵图形变换特效
Jan 26 Javascript
VUEJS实战之修复错误并且美化时间(2)
Jun 13 Javascript
jQuery事件处理的特征(事件命名机制)
Aug 23 Javascript
JSON与String互转的实现方法(Javascript)
Sep 27 Javascript
关于javascript获取内联样式与嵌入式样式的实例
Jun 01 Javascript
详解webpack2+node+react+babel实现热加载(hmr)
Aug 24 Javascript
node.js实现为PDF添加水印的示例代码
Dec 05 Javascript
VSCode写vue项目一键生成.vue模版,修改定义其他模板的方法
Apr 17 Javascript
javascript实现移动端红包雨页面
Jun 23 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
smarty 原来也不过如此~~呵呵
2006/11/25 PHP
使用YUI+Ant 实现JS CSS压缩
2014/09/02 PHP
利用PHP扩展Xhprof分析项目性能实践教程
2018/09/05 PHP
tp5.1 框架数据库-数据集操作实例分析
2020/05/26 PHP
javascript 模拟JQuery的Ready方法实现并出现的问题
2009/12/06 Javascript
js 编码转换 gb2312 和 utf8 互转的2种方法
2013/08/07 Javascript
js的alert样式如何更改如背景颜色
2014/01/22 Javascript
JavaScript导出Excel实例详解
2014/11/25 Javascript
node.js中的fs.rename方法使用说明
2014/12/16 Javascript
JS正则表达式修饰符global(/g)用法分析
2016/12/27 Javascript
如何写好你的JavaScript【推荐】
2017/03/02 Javascript
angularjs+bootstrap菜单的使用示例代码
2017/03/07 Javascript
Webpack中css-loader和less-loader的使用教程
2017/04/27 Javascript
React-Native做一个文本输入框组件的实现代码
2017/08/10 Javascript
快速解决select2在bootstrap模态框中下拉框隐藏的问题
2018/08/10 Javascript
在Create React App中使用CSS Modules的方法示例
2019/01/15 Javascript
js实现带有动画的返回顶部
2020/08/09 Javascript
Python检测网站链接是否已存在
2016/04/07 Python
对Python 3.2 迭代器的next函数实例讲解
2018/10/18 Python
Python将列表数据写入文件(txt, csv,excel)
2019/04/03 Python
Python3+Appium安装使用教程
2019/07/05 Python
Flask配置Cors跨域的实现
2019/07/12 Python
使用django的ORM框架按月统计近一年内的数据方法
2019/07/18 Python
Python 没有main函数的原因
2020/07/10 Python
Django扫码抽奖平台的配置过程详解
2021/01/14 Python
python 使用OpenCV进行简单的人像分割与合成
2021/02/02 Python
基于CSS3实现的黑色个性导航菜单效果
2015/09/14 HTML / CSS
京东国际站:JOYBUY
2017/11/23 全球购物
乌克兰香水和化妆品网站:Notino.ua
2018/03/26 全球购物
墨西哥皇宫度假村预订:Palace Resorts
2018/06/16 全球购物
作弊检讨书1000字
2014/02/01 职场文书
《鱼游到了纸上》教学反思
2014/02/20 职场文书
竞选大队委员演讲稿
2014/04/28 职场文书
工作保证书范文
2014/04/29 职场文书
投标邀请书范本
2015/02/02 职场文书
法制教育主题班会
2015/08/13 职场文书