如何用Vue实现一个全选指令
最近用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中
下面为实现代码:
- //全选
- 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);
- };
本人中途改行,入行1年出头,还有很多东西要学,有不对的地方,还请大家多多指教。为了勉励自己多些总结,开了个微信公众号(front-end-article),最近都在用vue做项目,近期应该会写一些关于vue的文章。有兴趣可以关注一下哦,或者投稿也可以,多多交流哈。
作者:对角另一面
来源:51CTO
如何用Vue实现一个全选指令相关推荐
- Vue实现购物车全选及价格计算
<vuejs实战>这本书中5.5是一道实战题:利用计算属性.指令等知识开发购物车. 练习1:在当前示例基础上扩展商品列表,新增一项是否选中该商品的功能,总价变为只计算选中商品的总价,同时提 ...
- ❤️❌ 如何用vue制作一个探探滑动组件
前言 嗨,说起探探想必各位程序汪都不陌生(毕竟妹子很多),能在上面丝滑的翻牌子,探探的的堆叠滑动组件起到了关键的作用,下面就来看看如何用vue写一个探探的堆叠组件 ? 一. 功能分析 简单使用下探探会 ...
- vue.js 实现全选,单选,计算商品总价格,商品件数
vue.js 实现全选,单选,计算商品总价格,商品件数 1.标签 <div id="main-body" class="box"> <div ...
- vue实现购物车全选,总计等功能
一.单价商品的小计 整个操作过程是,商品的数量是可以控制的,可增可减,最少为1.并且在数量的变化中,商品的小计也在变化. 二.单选选中商品 在购物车中,需要选择当前想买的商品,这一功能成为商品的单选, ...
- vue 多层双层全选_vue2.0 实现全选和全不选
实现思路: 1. v-model 一个收集所有input(除全选框外)数组checkModel ,vue会动态将其checked为true的input的value值存入数组checkModel里 2 ...
- vue 多层双层全选_vue多级复杂列表展开/折叠及全选/分组全选实现
首先,来看下效果图 在线体验地址:https://hxkj.vip/demo/multipleList/.温馨提示,打开之后按F12,使用手机模式食用,口味更佳! 可以看出,这个列表有三种展现形式: ...
- php 如何实现全选,如何用thinkphp框架实现全选,反选,全不选功能?
天涯尽头无女友 !function ($) {//全选 反选 全不选$("#selAll").click(function () {$(".lists :checkbox ...
- vue中实现全选多选
一.给全选框绑定点击事件 HTML: <div class="fixedLef" @click="chooseAllCart"><input ...
- vue 一个组件内多个弹窗_论如何用Vue实现一个弹窗-一个简单的组件实现
前言 最近在使用element-ui框架,用到了Dialog对话框组件,大致实现的效果,跟我之前自己在移动端项目里面弄的一个弹窗组件差不太多.然后就想着把这种弹窗组件的实现方式与大家分享一下,下面本文 ...
最新文章
- 超级直播tv港澳台版2020_直播链接 2020年泉州足球超级联赛 第一轮
- 关于DWG文件转换成PDF
- Visual C++ 编译器选项
- 前端学习(1870)vue之电商管理系统电商系统之配置message全局弹框组件
- Tensorflow模型加载与保存、Tensorboard简单使用
- 超级计算机子系统,大规模并行巨型机的并行I/O子系统
- fp16和fp32,神经网络混合精度训练,PYTORCH 采用FP16,Libtorch采用FP16,神经网络混合精度三种避免损失,TensorRT模型转换及部署(一)
- c语言输出英文字母表,菜鸟求助,写一个随机输出26个英文字母的程序
- 云教务学校管理系统源码
- win7怎么把计算机图标下的箭头掉,Win7桌面图标有小箭头怎么去掉?Win7去除桌面图标小箭头的方法...
- 如何解决语音社交的安全隐忧
- Vue的内置指令:v-if和v-show的区别
- beetl html 转义,Beetl解决XSS问题
- python动力学建模与仿真_发动机悬置python仿真计算
- 杨辉三角 118.杨辉三角 119.杨辉三角Ⅱ(数学解法)
- HDU1234 开门人和关门人
- 扡扫机器人_米家扫拖机器人:扫地拖地一把抓,小爱同学不落下
- 教你一招:如何快速制作来访登记二维码?
- css实现图片等宽高
- 什么是股票量化研究?
热门文章
- 35. 脱壳篇-UPX和WinUpack压缩壳的使用和脱法
- linux常用命令(精)
- SpringBoot解决redirect参数中文乱码问题
- mongdb安装配置
- 【洛谷P1774】最接近神的人
- redis数据结构对象
- JS window对象 返回前一个浏览的页面 back()方法,加载 history 列表中的前一个 URL。 语法: window.history.back();...
- Linux Kernel File IO Syscall Kernel-Source-Code Analysis(undone)
- 【Socket】关于socket长连接的心跳包
- 【android】读取/res/raw目录下的文件