Vue中实作全选功能

问题描述:

参考Vue js 2.x - Select All Checkbox, 完成了全选的功能。

先上效果图:

Vue js 2.x - Select All Checkbox的原代码:

HTML:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<script src="https://cdn.jsdelivr.net/vue/latest/vue.js"></script>

<div id="app">
<h4>User</h4>
<div>
<table>
<tr>
<th>Name</th>
<th>Select All<input type="checkbox" @click="selectAll" v-model="allSelected" </th>
</tr>
<tr v-for="user in users">
<td>{{ user.name }}</td>
<td><input type="checkbox" v-model="userIds" @click="select" :value="user.id"> </td>
</tr>
</table>
</div>
<span>Selected Ids: {{ userIds }}</span>
</div>

JS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// taken from https://jsfiddle.net/okv0rgrk/3747/

new Vue({
el: '#app',
data: {
users: [
{ "id": "Shad", "name": "Shad" },
{ "id": "Duane", "name": "Duane" },
{ "id": "Myah", "name": "Myah" },
{ "id": "Kamron", "name": "Kamron" },
{ "id": "Brendon", "name": "Brendon" }
],
selected: [],
allSelected: false,
userIds: []
},
methods: {
selectAll: function() {
this.userIds = [];

if (this.allSelected) {
for (user in this.users) {
this.userIds.push(this.users[user].id.toString());
}
}
},
select: function() {
this.allSelected = false;
}
}
})

参考的这份代码里面,有个小小的bug,就是当选中所有的子选项时,全选没有被选中。

解决方法:

点击子选项的时候,调用的是select函数,初步的想法是修改select函数,当选中的选项userIds等于users中的所有的ids即可。

1
2
3
4
5
6
7
8
// 修改select
select: function() {
if (this.userIds.length == this.users.length) {
this.allSelected = true;
} else {
this.allSelected = false;
}
}

发现修改后,没有任何效果,此处有个坑:

1
<input type="checkbox" v-model="userIds" @click="select" :value="user.id">

这里v-model的userIds,其实对应的是checked之后的值,也就是点击完最后一个子选项时,调用select函数,此时this.userIds.length = this.users.length - 1, 解决方法也很简单,修改click事件为change事件即可。这样调用select时,userIds已经更新。

改进后的代码:

HTML:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<script src="https://cdn.jsdelivr.net/vue/latest/vue.js"></script>

<div id="app">
<h4>User</h4>
<div>
<table>
<tr>
<th>Name</th>
<th>Select All<input type="checkbox" @click="selectAll" v-model="allSelected" </th>
</tr>
<tr v-for="user in users">
<td>{{ user.name }}</td>
<td><input type="checkbox" v-model="userIds" @change="select" :value="user.id"> </td>
</tr>
</table>
</div>
<span>Selected Ids: {{ userIds }}</span>
</div>

JS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// taken from https://jsfiddle.net/okv0rgrk/3747/

new Vue({
el: '#app',
data: {
users: [
{ "id": "Shad", "name": "Shad" },
{ "id": "Duane", "name": "Duane" },
{ "id": "Myah", "name": "Myah" },
{ "id": "Kamron", "name": "Kamron" },
{ "id": "Brendon", "name": "Brendon" }
],
selected: [],
allSelected: false,
userIds: []
},
methods: {
selectAll() {
this.userIds = [];

if (this.allSelected) {
for (user in this.users) {
this.userIds.push(this.users[user].id.toString());
}
}
},
select() {
if (this.userIds.length == this.users.length) {
this.allSelected = true
} else {
this.allSelected = false;
}
}
}
})

Google时,看到有使用自定义组件的方式来实现全选功能的:用Vue实现一个全选指令,照着在nuxt下实作了下,发现坑有些多,作罢,后续解决了再补上。

参考:

Vue js 2.x - Select All Checkbox