导航
利用JS实现
大家都知道checkbox的选中状态是按照checked属性来判断的,如下
<input type="checkbox" checked="checked">
<input type="checkbox" checked="true">
以上的代码都能实现被选中的状态,于是套用vue的语法,很容易写出如下的代码:
<input type="checkbox" :checked="is_checked">
data:{
is_checked:true // truthy 为选中状态 falsy 为选不中状态
}
当然 里面is_checked 也可以是一个判断条件如下:
<input type="checkbox" :checked="1 == 1"> <!--当条件成立时选中,不成立时不选中-->
当然你可能发现了,说道现在,我们都没有实现多选功能,甚至连显示都没有实现,那我们一步步来,先不管能不能选中,先把checkbox输出出来,当然这个对大家没有什么难度。
<div v-for="(checkOne,index) in checkList">
<input type="checkbox" :checked="false">
<span>{{checkOne.name}}</span>
</div>
data:{
checkList:[
{'name':'老王'},
{'name':'小张'},
{'name':'王伯'}
]
}
但是我们还没有实现选中的状态,结合上面的选中的代码,我们继续完善代码
<div v-for="(checkOne,index) in checkList">
<input type="checkbox" :checked="checkStatusList.indexOf(checkOne.name)>=0">
<span>{{checkOne.name}}</span>
</div>
data:{
checkList:[
{'name':'老王'},
{'name':'小张'},
{'name':'王伯'}
],
checkStatusList:['老王']
}
1、checkStatusList.indexOf(checkOne.name)>=0 用checkOne.name在checkStatusList中的索引来判断,只要checkOne.name在checkStatusList中,他的索引就会大于等于0,更具这个熟悉我们可以判断选中状态
2、这边的选中状态当然可以加到checkList中,但是这样不方便后面的处理,而且我认为选择之和最后选择的结果应该分开放,如果您有更好的简介,请在评论区赐教!(先谢过大佬)
至此,我们已经完成了显示,并将相应的选择之选中。但是我们会发现一个问题,当我们选中小张时,这个时候checkStatusList里面并不会多出一个小张(白选),怎么办? 经验告诉我,没有什么是加一个方法解决不了的事儿,如果有,那就加俩个!于是就变成下面的样子:
<div v-for="(checkOne,index) in checkList" @click='checkedOne(checkOne.name)'>
<input type="checkbox" :checked="checkStatusList.indexOf(checkOne.name)>=0">
<span>{{checkOne.name}}</span>
</div>
data:{
checkList:[
{'name':'老王'},
{'name':'小张'},
{'name':'王伯'}
],
checkStatusList:['老王']
}
methods: {
checkedOne:function (value) {
// 同显示,判断是否存在的同时,获取其索引(如果存在的话)
var idIndex = this.checkStatusList.indexOf(value);
if (idIndex >= 0) {
// 如果已经包含了该id, 则去除(单选按钮由选中变为非选中状态)
this.checkStatusList.splice(idIndex, 1)
} else {
// 选中该checkbox
this.checkStatusList.push(value)
}
}
}
至此我们已经完成了复选框的选中和取消,结果我们可以用this.checkStatusList获取,但是有个问题万一人家要全选呢?大丈夫です,继续加个方法嘛!
<div @click='checkedAll'>
<input type="checkbox" :checked="this.checkStatusList.length == this.checkList.length">
<span v-show="this.checkStatusList.length == this.checkList.length">取消</span>
<span v-show="this.checkStatusList.length != this.checkList.length">全选</span>
</div>
<div v-for="(checkOne,index) in checkList" @click='checkedOne(checkOne.name)'>
<input type="checkbox" :checked="checkStatusList.indexOf(checkOne.name)>=0">
<span>{{checkOne.name}}</span>
</div>
data:{
checkList:[
{'name':'老王'},
{'name':'小张'},
{'name':'王伯'}
],
checkStatusList:['老王']
}
methods: {
//选择 取消单个
checkedOne:function (value) {
// 同显示,判断是否存在的同时,获取其索引(如果存在的话)
var idIndex = this.checkStatusList.indexOf(value);
if (idIndex >= 0) {
// 如果已经包含了该id, 则去除(单选按钮由选中变为非选中状态)
this.checkStatusList.splice(idIndex, 1)
} else {
// 选中该checkbox
this.checkStatusList.push(value)
}
},
//选择 取消单个
checkedAll:function () {
var _this = this;
if(this.checkStatusList.length < this.checkList.length){
//当选择中的个数和没选中的个数不相等的时候,说明并没有全部选中
//这个是时候应该触发全部选中操作
_this.checkStatusList = [];
this.checkList.forEach(function (one) {
_this.checkStatusList.push(one.name)
});
} else {
//当选择中的个数和没选中的个数相等的时候,说明已经全部选中
//这个是时候应该触发全部取消操作
this.checkStatusList = [];
}
},
}
这里面判断是否全选的逻辑存在漏洞,当数据错误的情况下甚至可能出现this.checkStatusList.length > this.checkList.length的情况,这个时候可能存在错误判断,严格意义上应该一个个循环判断出来,但是我能保证后端数据是正确的(蜜汁自信)。如果大佬们有什么更好的方法,请评论赐教!
至此,我们也实现了多选的基本功能。
v-model模式实现
当然首先第一反应是v-model,正常实现的方法是这样的:
<div v-for="(checkOne,index) in checkList">
<input type="checkbox" v-model="checkOne.state">
<span>{{checkOne.name}}</span>
</div>
data:{
checkList:[
{state:false,name:'1'},
{state:false,name:'2'},
{state:false,name:'3'},
{state:false,name:'4'}
]
},
methods:{
checkedOne:function(one){
one.state = !one.state;
}
}
但是我们发现我们想获取我们选择之的时候发现,我们不能直接用了,这个是我无法忍受的,于是我想到了对方法进行改进
data:{
checkList:[
{state:false,name:'1'},
{state:false,name:'2'},
{state:false,name:'3'},
{state:false,name:'4'}
]
},
mounted:function(){
var _this = this;
var res = ['1','2'] //这里是默认的选择之 实际使用过程中,可以由服务器渲染,或者异步获取
this.checkList.forEach(function (one,index) {
if(res.indexOf(one.name)>=0) _this.checkList[index].state = true;
});
},
computed: {
//获取最终的选择结果
checkRes: function () {
var res = [];
this.checkList.forEach(function (one) {
if(true == one.state) res.push(one.name)
});
return res;
}
},
methods:{
checkedOne:function(one){
one.state = !one.state;
}
}
利用computed,mounted来把最终的结果分离出来分离选择之和选择的结果,方便后期处理。
同上,我们也想实现全选和全部取消,介于我们已经用了计算方法,我们的代码可以写的更加骚气一点。
<div v-on:click="checkedAll">
<input type="checkbox" v-model="checkAll">
<span>全选</span>
</div>
<div v-for="(checkOne,index) in checkList">
<input type="checkbox" v-model="checkOne.state" v-on:click="checkedOne(checkOne)">
<span>{{checkOne.name}}</span>
</div>
data:{
checkList:[
{state:true,name:'1'},
{state:false,name:'2'},
{state:false,name:'3'},
{state:false,name:'4'}
]
},
mounted:function(){
var _this = this;
var res = ['1','2'] //这里是默认的选择之
this.checkList.forEach(function (one,index) {
if(res.indexOf(one.name)>=0) _this.checkList[index].state = true;
});
},
computed: {
checkAll:function (){
return this.checkRes.length == this.checkList.length;
},
checkRes: function () {
var res = [];
this.checkList.forEach(function (one) {
if(true == one.state) res.push(one.name)
});
return res;
}
},
methods:{
checkedOne:function(one){
one.state = !one.state;
},
checkedAll:function(){
var _this = this;
var checkType = (true == this.checkAll) ? true : false; // 循环中(true == this.checkAll)的结果会发生改变
this.checkList.forEach(function (one,index) {
if(true == checkType){
// 已经全选 走取消的逻辑
_this.checkList[index].state = false;
} else {
// 没有全选 走选中的逻辑
_this.checkList[index].state = true;
}
});
}
}
简单的说下思路,首先判断checkList和checkRes的长度(由于checkRes是有checkList计算出来的,完美的解决了上面的问题),判断之后,获取到一个值checkAll,然后更具checkAll来判断是需要全部取消还是全选。
感谢
后面的判断参考了大佬的代码,所以在写文章时甚至盗用了人家的方法名
—— [ vue 实现checkbox的全选,单选以及删除 — Iven_Han ]
BTW
作为一个csdn的新人,这次写文章的时候写了很多重复的代码,想方便大家ctrl-c,ctrl-v(凑字数)但是这样严重的影响阅读速度,大家帮我看下你更喜欢哪种方法1、精简版 2、字多版
咱不是专业的前端,虽然已经很仔细了,但是咱是个大马虎所以上文可能存在很多低级的错误,希望大佬能帮我指正,谢谢(如果你想引用咱的文章,请不要忘记加上链接,还有—— [ vue 实现checkbox的全选,单选以及删除 — Iven_Han ]