利用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 相关文章推荐
北京奥运官方网站幻灯切换效果flash版打包下载
Jan 30 Javascript
动态创建script在IE中缓存js文件时导致编码的解决方法
May 04 Javascript
jQuery Ajax使用实例
Apr 16 Javascript
【经验总结】编写JavaScript代码时应遵循的14条规律
Jun 20 Javascript
仿iframe效果Aajx文件上传实例
Nov 18 Javascript
利用JS轻松实现获取表单数据
Dec 06 Javascript
简单理解js的prototype属性及使用
Dec 07 Javascript
使用jquery datatable和bootsrap创建表格实例代码
Mar 17 Javascript
DataTables添加额外的查询参数和删除columns等无用参数实例
Jul 04 Javascript
vue2.x 父组件监听子组件事件并传回信息的方法
Jul 17 Javascript
vue.js实现会动的简历(包含底部导航功能,编辑功能)
Apr 08 Javascript
vue使用localStorage保存登录信息 适用于移动端、PC端
May 27 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获取表单中多个同名input元素的值
2014/03/20 PHP
如何实现iframe(嵌入式帧)的自适应高度
2006/07/26 Javascript
javascript实现仿银行密码输入框效果的代码
2007/12/13 Javascript
JS打印gridview实现原理及代码
2013/02/05 Javascript
js控制淡入淡出示例代码
2013/11/12 Javascript
如何判断鼠标是否在DIV的区域内
2013/11/13 Javascript
Javascript模仿淘宝信用评价实例(附源码)
2015/11/26 Javascript
Bootstrap实现下拉菜单效果
2016/04/29 Javascript
JS判断form内所有表单是否为空的简单实例
2016/09/09 Javascript
JS实现的适合做faq或menu滑动效果示例
2016/11/17 Javascript
JS中from 表单序列化提交的代码
2017/01/20 Javascript
jQuery使用正则验证15/18身份证的方法示例
2017/04/27 jQuery
浅谈JS对html标签的属性的干预以及对CSS样式表属性的干预
2017/06/25 Javascript
JavaScript Date对象应用实例分享
2017/10/30 Javascript
JS原型继承四步曲及原型继承图一览
2017/11/28 Javascript
在Vue项目中引入JQuery-ui插件的讲解
2019/01/27 jQuery
javascript for循环性能测试示例
2019/08/07 Javascript
javascript实现前端成语点击验证优化
2020/06/24 Javascript
vue 子组件修改data或调用操作
2020/08/07 Javascript
pymssql ntext字段调用问题解决方法
2008/12/17 Python
Python运维开发之psutil库的使用详解
2018/10/18 Python
python时间序列按频率生成日期的方法
2019/05/14 Python
python3应用windows api对后台程序窗口及桌面截图并保存的方法
2019/08/27 Python
PyTorch在Windows环境搭建的方法步骤
2020/05/12 Python
python读写数据读写csv文件(pandas用法)
2020/12/14 Python
阿里云:Aliyun.com
2017/02/15 全球购物
舒适的豪华鞋:Taryn Rose
2018/05/03 全球购物
什么是Web Service?
2012/07/25 面试题
办理居住证介绍信
2014/01/15 职场文书
幼儿教育感言
2014/02/05 职场文书
《两个铁球同时着地》教学反思
2014/02/13 职场文书
大学生秋游活动方案
2014/02/17 职场文书
致长跑运动员加油稿
2014/02/20 职场文书
机关道德讲堂实施方案
2014/03/15 职场文书
自主招生教师推荐信
2014/05/10 职场文书
大学开学感言
2015/08/01 职场文书