利用Vue.js指令实现全选功能


Posted in Javascript onSeptember 08, 2016

因为刚开始接触vue不久,全选的实现参考了知乎上的实现方法:

     1、从服务器拿到数据,为每个item设置checked属性

     2、计算选中的数量selectCount,如果选中的数量与selectItems的数量相等,则全选selectAll选中

     3、点全选时,将每个item的checked属性置为true,反选时置为false,

     4、每次selectItems的属性发生变化时,都将checked的为true的item放入数组checkedGroups中

下面为实现代码:

//全选
 data: function() {
  return {
   selectItems: [], // 从服务器拿到的数据
  }
 },
 computed: {
  // 全选checkbox绑定的model
  selectAll: {
   get: function() {
    return this.selectCount == this.selectItems.length;
   },
   set: function(value) {
    this.selectItems.forEach(function(item) {
     item.checked = value;
    });
    return value;
   }
  },
  //选中的数量
  selectCount: {
   get: function() {
    var i = 0;
    this.selectItems.forEach(function(item) {
     if (item.checked) {
      i++;
     }
    });
    return i;
   }
  },
  //选中的数组
  checkedGroups: {
   get: function() {
    var checkedGroups = [];
    this.selectItems.forEach(function(item) {
     if (item.checked) {
      checkedGroups.push(item);
     }
    });
    return checkedGroups;
   }
  }
 }

这种方法用起来不太方便,首先是很难复用,每次要用到的时候都需要写一次computed,其次是selectAll、checkedGroups、selectItems都已经固定,不太灵活。

所以在这次项目中,我用vue的指令重新实现了全选的功能,directive的思路其实跟computed差不多,先上代码:

export default {
 'check-all': {
  twoWay: true,
  params: ['checkData'],
  bind() {
   /**
    - 如果所有的列表的checked属性都为true,则选中全选框,否则不选中全选框
    */
   this.vm.$watch(this.params.checkData, (checkData) => {
    if (checkData.every((item) => item.checked)) {
     this.set(true);
    } else {
     this.set(false);
    }
   }, { 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;
    });
   }
  },
 },
};

调用:

<input type="checkbox" v-model="checkAll" v-check-all="checkAll" check-data="checkData">
  <ul>
   <li v-for="item in checkData">
    <input type="checkbox" v-model="item.checked">
    {{item.text}}
   </li>
  </ul>

先说说这样用的优点:

1、方便使用,在需要用的地方,写上v-check-all指令和check-data就可以

2、全选的model和数组名可以定制,用什么名字都可以,全选的model不想叫checkAll叫checkAllData也可以,数组不想叫checkData叫dataFromServer也可以。

在指令中,指定twoWay为true,就可以用this.set(value)来设置checkAll的值,用params接收绑定指令元素上的属性值checkData,也就是需要操作的数组。

this.vm获取使用指令的上下文,调用上下文的$watch来监听checkData的变化,如果checkData全部选中,则设置checkAll为true,否则设置checkAll为false。

当指令值(checkAll)发生变化,如果为true,则将checkData的checked属性都设为true,否则为false。至此,一个全选的指令就完成了。

在做这个全选指令的时候,本来想用paramWatchers来监听checkData的变化的,但是发觉checkData变动时,并不会触发paramWatchers的回调,后来看了一下源码才发现,paramWatchers其实也是调用了$watch,但是不支持深度检测:

Directive.prototype._setupParamWatcher = function (key, expression) {
 var self = this;
 var called = false;
 var unwatch = (this._scope || this.vm).$watch(expression, function (val, oldVal) {
 self.params[key] = val;
 // since we are in immediate mode,
 // only call the param change callbacks if this is not the first update.
 if (called) {
  var cb = self.paramWatchers && self.paramWatchers[key];
  if (cb) {
  cb.call(self, val, oldVal);
  }
 } else {
  called = true;
 }
 }, {
 immediate: true,
 user: false
 });(this._paramUnwatchFns || (this._paramUnwatchFns = [])).push(unwatch);
};

总结

以上就是这篇文章的全部内容,有不对的地方,还请大家多多指教。希望这篇文章的内容对大家能有所帮助。

Javascript 相关文章推荐
jquery获得页面元素的坐标值实现思路及代码
Apr 15 Javascript
js style动态设置table高度
Oct 21 Javascript
JavaScript正则表达式中的ignoreCase属性使用详解
Jun 16 Javascript
javascript实现图片延迟加载方法汇总(三种方法)
Aug 27 Javascript
干货分享:让你分分钟学会javascript闭包
Dec 25 Javascript
原生JS实现风箱式demo,并封装了一个运动框架(实例代码)
Jul 22 Javascript
分享JavaScript监听全部Ajax请求事件的方法
Aug 28 Javascript
BootStrap3使用错误记录及解决办法
Dec 22 Javascript
JS正则获取HTML元素的方法
Mar 31 Javascript
vue axios整合使用全攻略
May 24 Javascript
jQuery实现的老虎机跑动效果示例
Dec 29 jQuery
Vue 同步异步存值取值实现案例
Aug 05 Javascript
AngularJS 实现JavaScript 动画效果详解
Sep 08 #Javascript
javascript使用 concat 方法对数组进行合并的方法
Sep 08 #Javascript
jQuery插入节点和移动节点用法示例(insertAfter、insertBefore方法)
Sep 08 #Javascript
jQuery删除节点用法示例(remove方法)
Sep 08 #Javascript
jQuery复制节点用法示例(clone方法)
Sep 08 #Javascript
jQuery替换节点用法示例(使用replaceWith方法)
Sep 08 #Javascript
jQuery元素属性操作实例(设置、获取及删除元素属性)
Sep 08 #Javascript
You might like
php实现mysql封装类示例
2014/05/07 PHP
destoon文章模块调用企业会员资料的方法
2014/08/22 PHP
Yii框架模拟组件调用注入示例
2019/11/11 PHP
JQuery index()方法使用代码
2010/06/02 Javascript
JS数组去重与取重的示例代码
2014/01/24 Javascript
extjs 如何给column 加上提示
2014/07/29 Javascript
js实现右键自定义菜单
2016/12/03 Javascript
JS 中使用Promise 实现红绿灯实例代码(demo)
2017/10/20 Javascript
微信小程序使用checkbox显示多项选择框功能【附源码下载】
2017/12/11 Javascript
微信小程序手机号码验证功能的实例代码
2018/08/28 Javascript
基于Vue实现可以拖拽的树形表格实例详解
2018/10/18 Javascript
Vue 刷新当前路由的实现代码
2019/09/26 Javascript
[02:32]DOTA2亚洲邀请赛 C9战队出场宣传片
2015/02/07 DOTA
[01:06:32]DOTA2上海特级锦标赛D组资格赛#1 EG VS VP第一局
2016/02/28 DOTA
Python 编码Basic Auth使用方法简单实例
2017/05/25 Python
Django项目中包含多个应用时对url的配置方法
2018/05/30 Python
Python3.5 处理文本txt,删除不需要的行方法
2018/12/10 Python
对python 多个分隔符split 的实例详解
2018/12/20 Python
Python中zip()函数的解释和可视化(实例详解)
2020/02/16 Python
Python bisect模块原理及常见实例
2020/06/17 Python
django 模型字段设置默认值代码
2020/07/15 Python
Python实现京东抢秒杀功能
2021/01/25 Python
详解CSS3中@media的实际使用
2015/08/04 HTML / CSS
HTML5中div、article、section的区别及使用介绍
2013/08/14 HTML / CSS
美国知名的网上鞋类及相关服装零售商:Shoes.com
2017/05/06 全球购物
C#面试问题
2016/07/29 面试题
大学毕业感言
2014/01/10 职场文书
医学生自我评价
2014/01/27 职场文书
医科大学毕业生自荐信
2014/02/03 职场文书
承诺书的格式范文
2014/03/28 职场文书
党员弘扬焦裕禄精神思想汇报
2014/09/10 职场文书
中学教师个人总结
2015/02/10 职场文书
工程质量保证书
2015/05/09 职场文书
2015年“我们的节日·重阳节”活动总结
2015/07/29 职场文书
2019年大学推荐信
2019/06/24 职场文书
你知道哪几种MYSQL的连接查询
2021/06/03 MySQL