利用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入门—访问DOM对象方法
Jan 07 Javascript
JS实现进入页面时渐变背景色的方法
Feb 25 Javascript
jQuery向父辈遍历的简单方法
Sep 18 Javascript
jQuery实现的小图列表,大图展示效果幻灯片示例
Oct 25 Javascript
JS创建对象的写法示例
Nov 04 Javascript
domReady的实现案例
Nov 23 Javascript
浅谈JS验证表单文本域输入空格的问题
Feb 14 Javascript
javascript中json对象json数组json字符串互转及取值方法
Apr 19 Javascript
Vue2.0 vue-source jsonp 跨域请求
Aug 04 Javascript
JavaScript实现区块链
Mar 14 Javascript
vue中多路由表头吸顶实现的几种布局方式
Apr 12 Javascript
JS window对象简单操作完整示例
Jan 14 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的一个登录的类 [推荐]
2007/03/16 PHP
php中计算未知长度的字符串哪个字符出现的次数最多的代码
2012/08/14 PHP
php中preg_match的isU代表什么意思
2015/10/01 PHP
什么是OneThink oneThink后台添加插件步骤
2016/04/13 PHP
详解Yii2高级版引入bootstrap.js的一个办法
2017/03/21 PHP
Javascript的并行运算实现代码
2010/11/19 Javascript
javascript处理table表格的代码
2010/12/06 Javascript
js中字符替换函数String.replace()使用技巧
2011/08/14 Javascript
JQuery为页面Dom元素绑定事件及解除绑定方法
2014/04/23 Javascript
JS触发服务器控件的单击事件(详解)
2016/08/06 Javascript
关于ES6的六个小特性(二)
2017/02/20 Javascript
详解从零搭建 vue2 vue-router2 webpack3 工程
2017/11/22 Javascript
vue.js element-ui validate中代码不执行问题解决方法
2017/12/18 Javascript
js自定义input文件上传样式
2018/10/26 Javascript
微信小程序实现两边小中间大的轮播效果的示例代码
2018/12/07 Javascript
基于vue.js组件实现分页效果
2018/12/29 Javascript
百度小程序之间的页面通信过程详解
2019/07/18 Javascript
vue + elementUI实现省市县三级联动的方法示例
2019/10/29 Javascript
vue中使用router全局守卫实现页面拦截的示例
2020/10/23 Javascript
详解Python中expandtabs()方法的使用
2015/05/18 Python
使用python对文件中的单词进行提取的方法示例
2018/12/21 Python
PyCharm-错误-找不到指定文件python.exe的解决方法
2019/07/01 Python
Python3之字节串bytes与字节数组bytearray的使用详解
2019/08/27 Python
解决pycharm中opencv-python导入cv2后无法自动补全的问题(不用作任何文件上的修改)
2020/03/05 Python
Python实现LR1文法的完整实例代码
2020/10/25 Python
Emporio Armani腕表天猫官方旗舰店:乔治·阿玛尼为年轻人设计的副线品牌
2017/07/02 全球购物
Mamaearth官方网站:印度母婴护理产品公司
2019/10/06 全球购物
什么是符号链接,什么是硬链接?符号链接与硬链接的区别是什么?
2013/05/03 面试题
建筑自我鉴定
2013/10/19 职场文书
医科大学生毕业的自我评价分享
2013/11/12 职场文书
公司总经理岗位职责
2014/03/15 职场文书
责任担保书范文
2014/05/21 职场文书
毕业季聚会祝酒词!
2019/07/04 职场文书
解决redis sentinel 频繁主备切换的问题
2021/04/12 Redis
Python如何解决secure_filename对中文不支持问题
2021/07/16 Python
升级 Win11 还是坚守 Win10?微软 Win11 新系统缺失功能大盘点
2022/04/05 数码科技