利用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 相关文章推荐
js调用webservice中的方法实现思路及代码
Feb 25 Javascript
jQuery中queue()方法用法实例
Dec 29 Javascript
javascript弹出拖动窗口
Aug 11 Javascript
详解javascript事件冒泡
Jan 09 Javascript
js简单正则验证汉字英文及下划线的方法
Nov 28 Javascript
JS实现导出Excel的五种方法详解【附源码下载】
Mar 15 Javascript
vue 弹框产生的滚动穿透问题的解决
Sep 21 Javascript
使用vuex较为优雅的实现一个购物车功能的示例代码
Dec 09 Javascript
Vue-CLI与Vuex使用方法实例分析
Jan 06 Javascript
vue+iview框架实现左侧动态菜单功能的示例代码
Jul 23 Javascript
vue浏览器返回监听的具体步骤
Feb 03 Vue.js
JavaScript 声明私有变量的两种方式
Feb 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 第二节 数据类型之字符串类型
2012/04/28 PHP
PHP连接SQLServer2005的实现方法(附ntwdblib.dll下载)
2012/07/02 PHP
php使用substr()和strpos()联合查找字符串中某一特定字符的方法
2015/05/12 PHP
浅谈laravel数据库查询返回的数据形式
2019/10/21 PHP
javascript 嵌套的函数(作用域链)
2010/03/15 Javascript
js中根据字数截取字符串,不能截断url
2012/01/12 Javascript
使用javascript实现有效时间的控制,并显示将要过期的时间
2014/01/02 Javascript
JavaScript对HTML DOM使用EventListener进行操作
2015/10/21 Javascript
微信小程序 wx.request(object) API详解及实例代码
2016/09/30 Javascript
Ext JS 实现建议词模糊动态搜索功能
2017/05/13 Javascript
详解vue2.0脚手架的webpack 配置文件分析
2017/05/27 Javascript
jQuery上传插件webupload使用方法
2017/08/01 jQuery
jQuery的时间datetime控件在AngularJs中的使用实例(分享)
2017/08/17 jQuery
JS扩展String.prototype.format字符串拼接的功能
2018/03/09 Javascript
解决vue项目打包后提示图片文件路径错误的问题
2018/07/04 Javascript
微信小程序实现的自定义分享功能示例
2019/02/12 Javascript
Vue组件之高德地图地址选择功能的实例代码
2019/06/21 Javascript
微信小程序实现图片翻转效果的实例代码
2019/09/20 Javascript
jquery检测上传文件大小示例
2020/04/26 jQuery
vue动态设置页面title的方法实例
2020/08/23 Javascript
javascript代码实现简易计算器
2021/01/25 Javascript
Python下rrdtool模块的基本使用方法
2015/11/13 Python
浅谈Pycharm调用同级目录下的py脚本bug
2018/12/03 Python
django框架实现模板中获取request 的各种信息示例
2019/07/01 Python
Python3常见函数range()用法详解
2019/12/30 Python
python中wx模块的具体使用方法
2020/05/15 Python
英国羊绒服装购物网站:Pure Collection
2018/10/22 全球购物
应届生保险求职信
2013/11/11 职场文书
店长岗位的工作内容
2013/11/12 职场文书
关于旷工的检讨书
2014/02/02 职场文书
创先争优个人承诺书
2014/08/30 职场文书
民政局个人整改措施
2014/09/24 职场文书
大学教师个人总结
2015/02/10 职场文书
教师个人学习总结
2015/02/11 职场文书
运动会100米广播稿
2015/08/19 职场文书
2016国庆节67周年寄语
2015/12/07 职场文书