最近用vue做了两个项目,都需要实现全选反选的功能,两个项目用了两种实现方法,第一个项目用vue的computed,第二个项目用指令来实现,用起来,发觉指令更加方便。

第一次做全选的时候是刚开始接触vue不久,全选的实现参考了知乎(链接:https://www.zhihu.com/question/37833194/answer/91812053)上的实现方法:

1、从服务器拿到数据,为每个item设置checked属性

2、计算选中的数量selectCount,如果选中的数量与selectItems的数量相等,则全选selectAll选中

3、点全选时,将每个item的checked属性置为true,反选时置为false,

4、每次selectItems的属性发生变化时,都将checked的为true的item放入数组checkedGroups中

下面为实现代码:

  1. //全选
  2. data: function() {
  3. return {
  4. selectItems: [],  // 从服务器拿到的数据
  5. }
  6. },
  7. computed: {
  8. // 全选checkbox绑定的model
  9. selectAll: {
  10. get: function() {
  11. return this.selectCount == this.selectItems.length;
  12. },
  13. set: function(value) {
  14. this.selectItems.forEach(function(item) {
  15. item.checked = value;
  16. });
  17. return value;
  18. }
  19. },
  20. //选中的数量
  21. selectCount: {
  22. get: function() {
  23. var i = 0;
  24. this.selectItems.forEach(function(item) {
  25. if (item.checked) {
  26. i++;
  27. }
  28. });
  29. return i;
  30. }
  31. },
  32. //选中的数组
  33. checkedGroups: {
  34. get: function() {
  35. var checkedGroups = [];
  36. this.selectItems.forEach(function(item) {
  37. if (item.checked) {
  38. checkedGroups.push(item);
  39. }
  40. });
  41. return checkedGroups;
  42. }
  43. }
  44. }

这种方法用起来不太方便,首先是很难复用,每次要用到的时候都需要写一次computed,其次是selectAll、checkedGroups、selectItems都已经固定,不太灵活。

所以在这次项目中,我用vue的指令重新实现了全选的功能,directive的思路其实跟computed差不多,先上代码:

  1. export default {
  2. 'check-all': {
  3. twoWay: true,
  4. params: ['checkData'],
  5. bind() {
  6. /**
  7. - 如果所有的列表的checked属性都为true,则选中全选框,否则不选中全选框
  8. */
  9. this.vm.$watch(this.params.checkData, (checkData) => {
  10. if (checkData.every((item) => item.checked)) {
  11. this.set(true);
  12. } else {
  13. this.set(false);
  14. }
  15. }, { deep: true });
  16. },
  17. // checkAll发生更改时
  18. update(checkAll) {
  19. /**
  20. - 如果全选框被选中,则将列表的所有checked属性转为true,否则转为false
  21. */
  22. if (checkAll) {
  23. this.vm[this.params.checkData].forEach((item) => {
  24. item.checked = true;
  25. });
  26. } else {
  27. this.vm[this.params.checkData].forEach((item) => {
  28. item.checked = false;
  29. });
  30. }
  31. },
  32. },
  33. };

调用:

  1. <input type="checkbox" v-model="checkAll" v-check-all="checkAll" check-data="checkData">
  2. <ul>
  3. <li v-for="item in checkData">
  4. <input type="checkbox" v-model="item.checked">
  5. {{item.text}}
  6. </li>
  7. </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,但是不支持深度检测:

  1. Directive.prototype._setupParamWatcher = function (key, expression) {
  2. var self = this;
  3. var called = false;
  4. var unwatch = (this._scope || this.vm).$watch(expression, function (val, oldVal) {
  5. self.params[key] = val;
  6. // since we are in immediate mode,
  7. // only call the param change callbacks if this is not the first update.
  8. if (called) {
  9. var cb = self.paramWatchers && self.paramWatchers[key];
  10. if (cb) {
  11. cb.call(self, val, oldVal);
  12. }
  13. } else {
  14. called = true;
  15. }
  16. }, {
  17. immediate: true,
  18. user: false
  19. });(this._paramUnwatchFns || (this._paramUnwatchFns = [])).push(unwatch);
  20. };

本人中途改行,入行1年出头,还有很多东西要学,有不对的地方,还请大家多多指教。为了勉励自己多些总结,开了个微信公众号(front-end-article),最近都在用vue做项目,近期应该会写一些关于vue的文章。有兴趣可以关注一下哦,或者投稿也可以,多多交流哈。

作者:对角另一面

来源:51CTO

如何用Vue实现一个全选指令相关推荐

  1. Vue实现购物车全选及价格计算

    <vuejs实战>这本书中5.5是一道实战题:利用计算属性.指令等知识开发购物车. 练习1:在当前示例基础上扩展商品列表,新增一项是否选中该商品的功能,总价变为只计算选中商品的总价,同时提 ...

  2. ❤️❌ 如何用vue制作一个探探滑动组件

    前言 嗨,说起探探想必各位程序汪都不陌生(毕竟妹子很多),能在上面丝滑的翻牌子,探探的的堆叠滑动组件起到了关键的作用,下面就来看看如何用vue写一个探探的堆叠组件 ? 一. 功能分析 简单使用下探探会 ...

  3. vue.js 实现全选,单选,计算商品总价格,商品件数

    vue.js 实现全选,单选,计算商品总价格,商品件数 1.标签 <div id="main-body" class="box"> <div ...

  4. vue实现购物车全选,总计等功能

    一.单价商品的小计 整个操作过程是,商品的数量是可以控制的,可增可减,最少为1.并且在数量的变化中,商品的小计也在变化. 二.单选选中商品 在购物车中,需要选择当前想买的商品,这一功能成为商品的单选, ...

  5. vue 多层双层全选_vue2.0 实现全选和全不选

    实现思路: 1. v-model 一个收集所有input(除全选框外)数组checkModel ,vue会动态将其checked为true的input的value值存入数组checkModel里 2 ...

  6. vue 多层双层全选_vue多级复杂列表展开/折叠及全选/分组全选实现

    首先,来看下效果图 在线体验地址:https://hxkj.vip/demo/multipleList/.温馨提示,打开之后按F12,使用手机模式食用,口味更佳! 可以看出,这个列表有三种展现形式: ...

  7. php 如何实现全选,如何用thinkphp框架实现全选,反选,全不选功能?

    天涯尽头无女友 !function ($) {//全选 反选 全不选$("#selAll").click(function () {$(".lists :checkbox ...

  8. vue中实现全选多选

    一.给全选框绑定点击事件 HTML: <div class="fixedLef" @click="chooseAllCart"><input ...

  9. vue 一个组件内多个弹窗_论如何用Vue实现一个弹窗-一个简单的组件实现

    前言 最近在使用element-ui框架,用到了Dialog对话框组件,大致实现的效果,跟我之前自己在移动端项目里面弄的一个弹窗组件差不太多.然后就想着把这种弹窗组件的实现方式与大家分享一下,下面本文 ...

最新文章

  1. 超级直播tv港澳台版2020_直播链接 2020年泉州足球超级联赛 第一轮
  2. 关于DWG文件转换成PDF
  3. Visual C++ 编译器选项
  4. 前端学习(1870)vue之电商管理系统电商系统之配置message全局弹框组件
  5. Tensorflow模型加载与保存、Tensorboard简单使用
  6. 超级计算机子系统,大规模并行巨型机的并行I/O子系统
  7. fp16和fp32,神经网络混合精度训练,PYTORCH 采用FP16,Libtorch采用FP16,神经网络混合精度三种避免损失,TensorRT模型转换及部署(一)
  8. c语言输出英文字母表,菜鸟求助,写一个随机输出26个英文字母的程序
  9. 云教务学校管理系统源码
  10. win7怎么把计算机图标下的箭头掉,Win7桌面图标有小箭头怎么去掉?Win7去除桌面图标小箭头的方法...
  11. 如何解决语音社交的安全隐忧
  12. Vue的内置指令:v-if和v-show的区别
  13. beetl html 转义,Beetl解决XSS问题
  14. python动力学建模与仿真_发动机悬置python仿真计算
  15. 杨辉三角 118.杨辉三角 119.杨辉三角Ⅱ(数学解法)
  16. HDU1234 开门人和关门人
  17. 扡扫机器人_米家扫拖机器人:扫地拖地一把抓,小爱同学不落下
  18. 教你一招:如何快速制作来访登记二维码?
  19. css实现图片等宽高
  20. 什么是股票量化研究?

热门文章

  1. 35. 脱壳篇-UPX和WinUpack压缩壳的使用和脱法
  2. linux常用命令(精)
  3. SpringBoot解决redirect参数中文乱码问题
  4. mongdb安装配置
  5. 【洛谷P1774】最接近神的人
  6. redis数据结构对象
  7. JS window对象 返回前一个浏览的页面 back()方法,加载 history 列表中的前一个 URL。 语法: window.history.back();...
  8. Linux Kernel File IO Syscall Kernel-Source-Code Analysis(undone)
  9. 【Socket】关于socket长连接的心跳包
  10. 【android】读取/res/raw目录下的文件