Vue中实作全选功能

Select All in Vue。

问题描述

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

先上效果图:

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

HTML:

<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:

// 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即可。

// 修改select
select: function() {
    if (this.userIds.length == this.users.length) {
        this.allSelected = true;
    } else {
        this.allSelected = false;
    }
}

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

<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:

<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:

// 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