利用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 相关文章推荐
为指定的元素添加遮罩层的示例代码
Jan 15 Javascript
详解JavaScript中undefined与null的区别
Mar 29 Javascript
Javascript中3个需要注意的运算符
Apr 02 Javascript
JavaScript控制浏览器全屏及各种浏览器全屏模式的方法、属性和事件
Dec 20 Javascript
微信小程序 Video API实例详解
Oct 02 Javascript
Vue 过渡(动画)transition组件案例详解
Jan 22 Javascript
解决Vue axios post请求,后台获取不到数据的问题方法
Aug 11 Javascript
vue集成百度UEditor富文本编辑器使用教程
Sep 21 Javascript
React 全自动数据表格组件——BodeGrid的实现思路
Jun 12 Javascript
Vue配置marked链接添加target=&quot;_blank&quot;的方法
Jul 19 Javascript
学习LayUI时自研的表单参数校验框架案例分析
Jul 29 Javascript
JS面向对象编程——ES6 中class的继承用法详解
Mar 03 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中的strtr函数使用介绍(str_replace)
2011/10/20 PHP
PHP使用json_encode函数时不转义中文的解决方法
2014/11/12 PHP
PHP长网址与短网址的实现方法
2017/10/13 PHP
使用vs code编辑调试php配置的方法
2019/01/29 PHP
Swoole源码中如何查询Websocket的连接问题详解
2020/08/30 PHP
写了一个layout,拖动条连贯,内容区可为iframe
2007/08/19 Javascript
设为首页加入收藏兼容360/火狐/谷歌/IE等主流浏览器的代码
2013/03/26 Javascript
JQuery给元素添加/删除节点比如select
2013/04/02 Javascript
jquery事件与函数的使用介绍
2013/09/29 Javascript
js获取IFRAME当前的URL的方法
2013/11/13 Javascript
Jquery操作radio的简单实例
2014/01/06 Javascript
jquery统计用户选中的复选框的个数
2014/06/06 Javascript
原生javascript实现图片弹窗交互效果
2015/01/12 Javascript
Vue的事件响应式进度条组件实例详解
2018/02/04 Javascript
微信小程序canvas拖拽、截图组件功能
2018/09/04 Javascript
详解新手使用vue-router传参时注意事项
2019/06/06 Javascript
Vue-Cli 3.0 中配置高德地图的两种方式
2019/06/19 Javascript
es6中使用map简化复杂条件判断操作实例详解
2020/02/19 Javascript
jQuery实现推拉门效果
2020/10/19 jQuery
vue3.0搭配.net core实现文件上传组件
2020/10/29 Javascript
[02:23]2018DOTA2亚洲邀请赛趣味视频——反应测试
2018/04/04 DOTA
django模型中的字段和model名显示为中文小技巧分享
2014/11/18 Python
用python写的一个wordpress的采集程序
2016/02/27 Python
python代码实现逻辑回归logistic原理
2019/08/07 Python
python实现多进程按序号批量修改文件名的方法示例
2019/12/30 Python
Python过滤掉numpy.array中非nan数据实例
2020/06/08 Python
南非最大的花卉和送礼服务:NetFlorist
2017/09/13 全球购物
美国领先的男士和女士内衣购物网站:Freshpair
2019/02/25 全球购物
出国留学计划书
2014/04/27 职场文书
书香校园建设方案
2014/05/02 职场文书
教书育人演讲稿
2014/09/11 职场文书
派出所班子党的群众路线对照检查材料思想汇报
2014/10/01 职场文书
领导干部个人整改措施落实情况汇报
2014/10/29 职场文书
2015年档案管理员工作总结
2015/05/13 职场文书
小学生教师节广播稿
2015/08/19 职场文书
小学语文新课改心得体会
2016/01/22 职场文书