Javascript 选中所有复选框 vuejs

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33571382/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 15:14:15  来源:igfitidea点击:

Check all checkboxes vuejs

javascriptcheckbox

提问by haakym

I'm displaying a list of users in a table, each row has a checkbox to select the user and the checkbox value is the user's ID. The selected IDs are in turn displayed in a span below the table.

我在表中显示用户列表,每一行都有一个复选框来选择用户,复选框值是用户的 ID。选定的 ID 依次显示在表格下方的范围内。

How can I select all checkboxes and deselect all checkboxes on the click of a "select all" checkbox that I have in the header of my table? Do I interact with the DOM to do this or through the vue object, I'm thinking it should be the latter but quite unsure how to approach what appears to be an easy task?! Any help would be appreciated!

如何在单击表格标题中的“全选”复选框时选择所有复选框并取消选择所有复选框?我是与 DOM 交互来执行此操作还是通过 vue 对象进行交互,我认为应该是后者,但不确定如何处理看似简单的任务?!任何帮助,将不胜感激!

HTML

HTML

<div id="app">
    <h4>Users</h4>
    <div>
        <table>
            <tr>
                <th>Name</th>
                <th>Select <input type="checkbox" @click="selectAll"></th>
            </tr>
            <tr v-for="user in users">
                <td>{{ user.name }}</td>
                <td><input type="checkbox" v-model="selected" value="{{ user.id }}"></td>
            </tr>
        </table>
    </div>

    <span>Selected Ids: {{ selected| json }}</span>
</div>

Javascript/Vuejs

Javascript/Vuejs

new Vue({
    el: '#app',
    data: {
        users: [ 
            { "id": "1", "name": "Shad Jast", "email": "[email protected]", 
            { "id": "2", "name": "Duane Metz", "email": "[email protected]"}, 
            { "id": "3", "name": "Myah Kris", "email": "[email protected]"}, 
            { "id": "4", "name": "Dr. Kamron Wunsch", "email": "[email protected]"}, 
            { "id": "5", "name": "Brendon Rogahn", "email": "[email protected]"}
        ],
        selected: []
    },
    methods: {
        selectAll: function() {
            // ?
        }
    }
})

采纳答案by haakym

Adding my own answer as edits on the answer by nhydock weren't accepted (I think?).

添加我自己的答案作为 nhydock 对答案的编辑不被接受(我认为?)。

Solution selects and selects all.

解决方案全选。

HTML

HTML

<div id="app">
    <h4>User</h4>
        <div>
            <table>
                <tr>
                    <th>Name</th>
                    <th>Select <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" value="{{ user.id }}"></td>
                </tr>
            </table>
        </div>

        <span>Selected Ids: {{ userIds | json }}</span>
</div>

Javascript/Vuejs

Javascript/Vuejs

new Vue({
    el: '#app',
    data: {
        users: [ 
            { "id": "1", "name": "Shad Jast", "email": "[email protected]"}, 
            { "id": "2", "name": "Duane Metz", "email": "[email protected]"}, 
            { "id": "3", "name": "Myah Kris", "email": "[email protected]"}, 
            { "id": "4", "name": "Dr. Kamron Wunsch", "email": "[email protected]"}, 
            { "id": "5", "name": "Brendon Rogahn", "email": "[email protected]"}
        ],
        selected: [],
        allSelected: false,
        userIds: []
    },
    methods: {
        selectAll: function() {
            this.userIds = [];

            if (!this.allSelected) {
                for (user in this.users) {
                    this.userIds.push(this.users[user].id);
                }
            }
        },
    }
})

Working fiddle: https://jsfiddle.net/okv0rgrk/3747/

工作小提琴:https: //jsfiddle.net/okv0rgrk/3747/

回答by Rifki

I think @Jeremy's answer is cleaner way, but it require for checkedproperty on each user object which is makes no sense if the data come from an API request.

我认为@Jeremy 的答案是更简洁的方法,但它需要checked每个用户对象的属性,如果数据来自 API 请求,这将毫无意义。

Here is working and cleaner code for select/deselect all rows without having to add checkedproperty on user object:

这是用于选择/取消选择所有行的工作且更清晰的代码,而无需checked在用户对象上添加属性:

new Vue({
    el: '#app',
    data: {
        users: [ 
            { "id": "1", "name": "Shad Jast", "email": "[email protected]" },
            { "id": "2", "name": "Duane Metz", "email": "[email protected]" }, 
            { "id": "3", "name": "Myah Kris", "email": "[email protected]" }, 
            { "id": "4", "name": "Dr. Kamron Wunsch", "email": "[email protected]" }
        ],
        selected: []
    },
    computed: {
        selectAll: {
            get: function () {
                return this.users ? this.selected.length == this.users.length : false;
            },
            set: function (value) {
                var selected = [];

                if (value) {
                    this.users.forEach(function (user) {
                        selected.push(user.id);
                    });
                }

                this.selected = selected;
            }
        }
    }
});
<script src="https://cdn.jsdelivr.net/vue/latest/vue.js"></script>

<div id="app">
<h4>User</h4>
<div>
    <table>
        <tr>
            <th><input type="checkbox" v-model="selectAll"></th>
            <th align="left">Name</th>
        </tr>
        <tr v-for="user in users">
            <td>
                <input type="checkbox" v-model="selected" :value="user.id" number>
            </td>
            <td>{{ user.name }}</td>
        </tr>
    </table>
</div>
</div>

Please note that the numberattribute on row's checkbox is required, otherwise you have to push the user id selectAllmethod as a string, like selected.push(user.id.toString());

请注意,number行复选框上的属性是必需的,否则您必须将用户 idselectAll方法作为字符串推送,例如selected.push(user.id.toString());

回答by Jeremy

How about my answer, with less properties, easy to understand?

我的答案怎么样,属性少,容易理解?

new Vue({
  el: '#app',
  data: {
    users: [{
      "id": "1",
      "name": "Shad Jast",
      "email": "[email protected]",
      'checked': false
    }, {
      "id": "2",
      "name": "Duane Metz",
      "email": "[email protected]",
      'checked': false
    }, {
      "id": "3",
      "name": "Myah Kris",
      "email": "[email protected]",
      'checked': false
    }, {
      "id": "4",
      "name": "Dr. Kamron Wunsch",
      "email": "[email protected]",
      'checked': false
    }, ],

  },
  computed: {
    selectAll: function() {
      return this.users.every(function(user){
        return user.checked;
      });
    }
  },
  methods: {
    toggleSelect: function() {
      var select = this.selectAll;
      this.users.forEach(function(user) {

        user.checked = !select;

      });
      this.selectAll = !select;
    },

  }
});
<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
          <input type="checkbox" @click="toggleSelect" :checked="selectAll">
        </th>
      </tr>
      <tr v-for="user in users">
        <td>{{ user.name }}</td>
        <td>
          <input type="checkbox" v-model="user.checked">
        </td>
      </tr>
    </table>
  </div>

</div>

回答by jh-thank-you

I want to thank everyone for sharing their solutions. It has been a big help with learning. A developer on gitter helped me to add a Default checkbox that will select a subset of the array that has a property called "default" set to true.

我要感谢大家分享他们的解决方案。对学习有很大帮助。gitter 上的一位开发人员帮助我添加了一个默认复选框,该复选框将选择数组的一个子集,该子集的名为“default”的属性设置为 true。

here is the code:

这是代码:

// based on https://jsfiddle.net/okv0rgrk/3747/

new Vue({
    el: '#app',
    data: {
        selected: [],
        defaultSelects: [],
        selectsArray: [ 

            {id: 'automotive', name: 'Automotive', class: 'industry', default: false},

            {id: 'beauty', name: 'Beauty', class: 'industry', default: true},

            {id: 'branding', name: 'Branding', class: 'industry', default: true},

            {id: 'btob', name: 'B to B', class: 'industry', default: false}
        ],
        selected: [],
    },
    computed: {
      defaultChecked: {
        get () {
          let defaults = this.selectsArray.filter(item => item.default).map(item => item.id)
          const hasAllItems = (baseArr, haystack) => haystack.every(item => baseArr.includes(item))
          const hasSameItems = (baseArr, haystack) => hasAllItems(baseArr, haystack) && hasAllItems(haystack, baseArr)
          return hasSameItems(this.selected, defaults)
        },
        set (value) {
          this.selected = []

          if (value) {
            this.selectsArray.forEach((select) => {
              if (select.default) {
                this.selected.push(select.id)
              }
            });
          }
        }
      }, // END defaultChecked
      selectAll: {
        get () {
          return this.selected.length === this.selectsArray.length
        },
        set (value) {
          this.selected = []

          if (value) {
            this.selectsArray.forEach((select) => {
              this.selected.push(select.id)
            })
          }
        }
      }, // END selectAll
    }
})
<script src="https://cdn.jsdelivr.net/vue/latest/vue.js"></script>

<div id="app">
          
<div id="default-settings">

<label class="pref-button"><input type="checkbox" v-model="defaultChecked"><span>Default</span></label>

<label class="pref-button"><input type="checkbox" v-model="selectAll"><span>Select All</span></label>

</div>    
          
<label :for="select.id" v-for="select in selectsArray" v-bind:key="select.id"><input :value="select.id" v-model="selected" :id="select.id" :sector="select.id" :class="select.class" :default="select.default" type="checkbox">{{ select.name }}</label>

<span>Selected Ids: {{ selected }}</span>
  
</div>

回答by nhydock

All you have to do is add your users, using their ID since that's how you're referencing their values with the checkbox, and add them into your selected array.

您所要做的就是添加您的用户,使用他们的 ID,因为这就是您使用复选框引用他们的值的方式,并将它们添加到您选择的数组中。

selectAll: function() {
    this.selected = [];
    for (user in this.users) {
        this.selected.push(this.users[user].id);
    }
}

Running JSFiddle

运行 JSFiddle

回答by D-Marc

Basically the same answer as @Rifki, but checks if each element exists in both, rather than just the length.

基本上与@Rifki 的答案相同,但检查每个元素是否存在于两者中,而不仅仅是长度。

new Vue({
  el: '#app',
  data: {
    users: [{
        "id": "1",
        "name": "Shad Jast",
        "email": "[email protected]"
      },
      {
        "id": "2",
        "name": "Duane Metz",
        "email": "[email protected]"
      },
      {
        "id": "3",
        "name": "Myah Kris",
        "email": "[email protected]"
      },
      {
        "id": "4",
        "name": "Dr. Kamron Wunsch",
        "email": "[email protected]"
      }
    ],
    selected: []
  },
  computed: {
    selectAll: {
      get() {
        if (this.users && this.users.length > 0) { // A users array exists with at least one item
          let allChecked = true;

          for (const user of this.users) {
            if (!this.selected.includes(user.id)) {
              allChecked = false; // If even one is not included in array
            }
            
            // Break out of loop if mismatch already found
            if(!allChecked) break;
          }

          return allChecked;
        }

        return false;
      },
      set(value) {
        const checked = [];

        if (value) {
          this.users.forEach((user) => {
            checked.push(user.id);
          });
        }

        this.selected = checked;
      }
    },
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <h4>User</h4>
  <div>
    <table>
      <tr>
        <th><input type="checkbox" v-model="selectAll"></th>
        <th align="left">Name</th>
      </tr>
      <tr v-for="user in users">
        <td>
          <input type="checkbox" v-model="selected" :value="user.id" number>
        </td>
        <td>{{ user.name }}</td>
      </tr>
    </table>
  </div>
</div>

回答by Richard Feliciano

i think this could be a little bit easier.

我认为这可能会更容易一些。

selectAll: function (isSelected) {
  if (!isSelected) {
    this.ids = []
    return false
  }
  if (isSelected) {
    this.rows.map(item => this.ids.push(item.id))
  }
}

回答by Flik Shen

I have a more simple solution as following and it has all you want. The real data should be put into a map indexed the name as the label of checkbox for future easy to access.

我有一个更简单的解决方案,如下所示,它有你想要的一切。真实的数据应该放在一个地图中,索引名称作为复选框的标签,以便将来易于访问。

<template>
  <div align="left">
    <div>
      <input type="checkbox" id="all" :checked="allNamesSelected" @click="selectAll()">
      <label for="all">All</label>
    </div>
    <div v-for="(name) in names" :key="name">
      <input type="checkbox" :id="name" :value="name" :check="isChecked(name)" v-model="selectedNames">
      <label :for="name">{{name}}</label>
    </div>
  </div>
</template>

<script>
export default {
    data() {
        return {
            names: ['Automotive', 'Beauty', 'Branding', 'B to B'],
            selectedNames: [],
        }; 
    },
    computed: {
        allNamesSelected() {
            return this.names.length == this.selectedNames.length;
        },
    },
    methods: {
        selectAll() {
            if (this.allNamesSelected) {
                this.selectedNames = [];
            } else {
                this.selectedNames = this.names.slice();
            }
        },
        isChecked(name) {
            return this.selectedNames.includes(name);
        }
    }
}
</script>

回答by Oleg Bolden

Often there is no need to display selected IDs below the table. In such cases the above code can be simplified to:

通常不需要在表格下方显示选定的 ID。在这种情况下,上面的代码可以简化为:

HTML

HTML

<div id="app">
    <h4>Users</h4>
    <div>
        <table>
            <tr>
                <th>Name</th>
                <th>Select <input type="checkbox" v-model="selectAll"></th>
            </tr>
            <tr v-for="user in users">
                <td>{{ user.name }}</td>
                <td><input type="checkbox" :value="user.id" :checked="selectAll"></td>
            </tr>
        </table>
    </div>
</div>

VueJs

VueJS

new Vue({
    el: '#app',
    data: {
        users: [ 
            { "id": "1", "name": "Shad Jast", "email": "[email protected]"}, 
            { "id": "2", "name": "Duane Metz", "email": "[email protected]"}, 
            { "id": "3", "name": "Myah Kris", "email": "[email protected]"}, 
            { "id": "4", "name": "Dr. Kamron Wunsch", "email": "[email protected]"}, 
            { "id": "5", "name": "Brendon Rogahn", "email": "[email protected]"}
        ],
        selectAll: false
    }
})