利用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之字体大小的设置方法
Feb 27 Javascript
实现js保留小数点后N位的代码
Nov 13 Javascript
jquery实现鼠标悬浮停止轮播特效
Aug 20 Javascript
第十篇BootStrap轮播插件使用详解
Jun 21 Javascript
Augularjs-起步详解
Jul 08 Javascript
实例详解jQuery的无new构建
Aug 02 Javascript
jq实现左滑显示删除按钮,点击删除实现删除数据功能(推荐)
Aug 23 Javascript
原生js仿淘宝网商品放大镜效果
Feb 28 Javascript
微信小程序多张图片上传功能
Jun 07 Javascript
JavaScript私有变量实例详解
Jan 24 Javascript
JS函数参数的传递与同名参数实例分析
Mar 16 Javascript
gojs实现蚂蚁线动画效果
Feb 18 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
file_get_contents(&quot;php://input&quot;, &quot;r&quot;)实例介绍
2013/07/01 PHP
PHP7.0版本备注
2015/07/23 PHP
深入剖析浏览器退出之后php还会继续执行么
2016/05/17 PHP
浅谈PHP发送HTTP请求的几种方式
2017/07/25 PHP
JavaScript 序列化对象实现代码
2009/12/18 Javascript
通过继承IHttpHandle实现JS插件的组织与管理
2010/07/13 Javascript
js substr、substring和slice使用说明小记
2011/09/15 Javascript
js中复制行和删除行的操作实例
2013/06/25 Javascript
JavaScript sup方法入门实例(把字符串显示为上标)
2014/10/20 Javascript
jQuery中animate动画第二次点击事件没反应
2015/05/07 Javascript
jQuery结合AJAX之在页面滚动时从服务器加载数据
2015/06/30 Javascript
使用BootStrap建立响应式网页——通栏轮播图(carousel)
2016/12/21 Javascript
微信小程序 页面之间传参实例详解
2017/01/13 Javascript
js实现模糊匹配功能
2017/02/15 Javascript
使用selenium抓取淘宝的商品信息实例
2018/02/06 Javascript
bootstrap 路径导航 分页 进度条的实例代码
2018/08/06 Javascript
node.js爬取中关村的在线电瓶车信息
2018/11/13 Javascript
typescript配置alias的详细步骤
2020/08/12 Javascript
Python中的字典与成员运算符初步探究
2015/10/13 Python
Python实现简单多线程任务队列
2016/02/27 Python
Python 提取dict转换为xml/json/table并输出的实现代码
2016/08/28 Python
python 移动图片到另外一个文件夹的实例
2019/01/10 Python
通过cmd进入python的步骤
2020/06/16 Python
Python 如何调试程序崩溃错误
2020/08/03 Python
详解向scrapy中的spider传递参数的几种方法(2种)
2020/09/28 Python
python爬取youtube视频的示例代码
2021/03/03 Python
css3实现椭圆轨迹旋转的示例代码
2018/10/29 HTML / CSS
巴黎卡诗美国官方网站:始于1964年的头发头皮护理专家
2017/07/10 全球购物
Delphi CS笔试题
2014/01/04 面试题
机电一体化毕业生自荐信
2014/06/19 职场文书
药剂专业求职信
2014/06/20 职场文书
干部作风建设工作总结
2014/10/29 职场文书
2015年音乐教师个人工作总结
2015/05/20 职场文书
pytorch实现手写数字图片识别
2021/05/20 Python
Django实现聊天机器人
2021/05/31 Python
Java并发编程之Executor接口的使用
2021/06/21 Java/Android