【问题标题】:Check all checkboxes vuejs检查所有复选框vuejs
【发布时间】:2016-02-07 20:54:16
【问题描述】:

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

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

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

new Vue({
    el: '#app',
    data: {
        users: [ 
            { "id": "1", "name": "Shad Jast", "email": "pfeffer.matt@yahoo.com", 
            { "id": "2", "name": "Duane Metz", "email": "mohammad.ferry@yahoo.com"}, 
            { "id": "3", "name": "Myah Kris", "email": "evolkman@hotmail.com"}, 
            { "id": "4", "name": "Dr. Kamron Wunsch", "email": "lenora95@leannon.com"}, 
            { "id": "5", "name": "Brendon Rogahn", "email": "verlie.buckridge@yahoo.com"}
        ],
        selected: []
    },
    methods: {
        selectAll: function() {
            // ?
        }
    }
})

【问题讨论】:

    标签: javascript checkbox


    【解决方案1】:

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

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

    Running JSFiddle

    【讨论】:

    • 感谢您的回复。这对于选择所有值非常有用,但是取消选择呢?
    • 我猜我可以检查选中的所有内容是真还是假,如果为假,则从选中的内容中删除所有内容?打算试试你的小提琴。
    • 哇!得到它的工作,我会更新你的答案一点,希望没关系?用解决方案更新了你的小提琴。感谢您的帮助好友
    【解决方案2】:

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

    解决方案选择并全选。

    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

    new Vue({
        el: '#app',
        data: {
            users: [ 
                { "id": "1", "name": "Shad Jast", "email": "pfeffer.matt@yahoo.com"}, 
                { "id": "2", "name": "Duane Metz", "email": "mohammad.ferry@yahoo.com"}, 
                { "id": "3", "name": "Myah Kris", "email": "evolkman@hotmail.com"}, 
                { "id": "4", "name": "Dr. Kamron Wunsch", "email": "lenora95@leannon.com"}, 
                { "id": "5", "name": "Brendon Rogahn", "email": "verlie.buckridge@yahoo.com"}
            ],
            selected: [],
            allSelected: false,
            userIds: []
        },
        methods: {
            selectAll: function() {
                this.userIds = [];
    
                if (!this.allSelected) {
                    for (user in this.users) {
                        this.userIds.push(this.users[user].id);
                    }
                }
            },
        }
    })
    

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

    【讨论】:

    • 问题:1)全选; 2)取消选择一项。 SelectAll 复选框应该被取消选中。
    • @Sigma 很好,我为小提琴添加了一个修复程序,也许不是一个很好的解决方案,但它确实有效。随意发布您自己的解决方案。
    • 在方法 selectAll 中应该是“if(this.allSelected)”而不是“if(!this.allSelected)”。没有必要使用! .
    【解决方案3】:

    我的回答怎么样,属性少,通俗易懂?

    new Vue({
      el: '#app',
      data: {
        users: [{
          "id": "1",
          "name": "Shad Jast",
          "email": "pfeffer.matt@yahoo.com",
          'checked': false
        }, {
          "id": "2",
          "name": "Duane Metz",
          "email": "mohammad.ferry@yahoo.com",
          'checked': false
        }, {
          "id": "3",
          "name": "Myah Kris",
          "email": "evolkman@hotmail.com",
          'checked': false
        }, {
          "id": "4",
          "name": "Dr. Kamron Wunsch",
          "email": "lenora95@leannon.com",
          '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>

    【讨论】:

    • 我猜它依赖于每个具有'checked': false的数据项?
    • this.selectAll = !select; 是不必要的,因为 this.selectAll 将始终依赖是否所有用户的已检查属性都已检查~
    【解决方案4】:

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

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

    new Vue({
        el: '#app',
        data: {
            users: [ 
                { "id": "1", "name": "Shad Jast", "email": "pfeffer.matt@yahoo.com" },
                { "id": "2", "name": "Duane Metz", "email": "mohammad.ferry@yahoo.com" }, 
                { "id": "3", "name": "Myah Kris", "email": "evolkman@hotmail.com" }, 
                { "id": "4", "name": "Dr. Kamron Wunsch", "email": "lenora95@leannon.com" }
            ],
            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>

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

    【讨论】:

    • 非常聪明和干净的解决方案 :) 谢谢。 p.s.首先 this.selected = selected;是多余的
    • @KarolFiturski 啊,是的,谢谢提醒,会更新它。
    • user.id.toString() 伙计,你真的救了我的命。 3 小时的闲逛
    • 谢谢。这是一个聪明而简洁的解决方案。但是我只有一个疑问。为什么 setter 需要是计算属性? .不能只是一个更新 selected[] 状态的方法吗?
    • 对于任何想要检查所有元素是否确实存在于两者中的人,而不仅仅是长度stackoverflow.com/a/58987192
    【解决方案5】:

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

    代码如下:

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

    【讨论】:

      【解决方案6】:

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

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

      【讨论】:

        【解决方案7】:

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

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

        【讨论】:

          【解决方案8】:

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

          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

          new Vue({
              el: '#app',
              data: {
                  users: [ 
                      { "id": "1", "name": "Shad Jast", "email": "pfeffer.matt@yahoo.com"}, 
                      { "id": "2", "name": "Duane Metz", "email": "mohammad.ferry@yahoo.com"}, 
                      { "id": "3", "name": "Myah Kris", "email": "evolkman@hotmail.com"}, 
                      { "id": "4", "name": "Dr. Kamron Wunsch", "email": "lenora95@leannon.com"}, 
                      { "id": "5", "name": "Brendon Rogahn", "email": "verlie.buckridge@yahoo.com"}
                  ],
                  selectAll: false
              }
          })
          

          【讨论】:

            【解决方案9】:

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

            new Vue({
              el: '#app',
              data: {
                users: [{
                    "id": "1",
                    "name": "Shad Jast",
                    "email": "pfeffer.matt@yahoo.com"
                  },
                  {
                    "id": "2",
                    "name": "Duane Metz",
                    "email": "mohammad.ferry@yahoo.com"
                  },
                  {
                    "id": "3",
                    "name": "Myah Kris",
                    "email": "evolkman@hotmail.com"
                  },
                  {
                    "id": "4",
                    "name": "Dr. Kamron Wunsch",
                    "email": "lenora95@leannon.com"
                  }
                ],
                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>

            【讨论】:

            • 取消选中父复选框时,所有子复选框都未选中。你能更新你的答案Vue版本:“^2.6.10”,
            • 也许我误解了你在说什么,但这是所问问题的预期结果。
            【解决方案10】:

            这是最简单的解决方案,仅使用 v-modelscomputed。不需要额外的数组、@click、:checked

            HTML

            <div id="app">
               <input type="checkbox" v-model="allSelected"> Select All
            
               <ul>
                  <li v-for="user in users">
                     <input type="checkbox" v-model="user.selected"> {{ user.name }}
                  </li>
               </ul>
            
               <button @click="getSelectedUsers">Get Selected Users</button>
            </div>
            

            JS

            new Vue({
              el: "#app",
              data: {
                users: [
                  {
                    id: 1,
                    name: "Alda Myrrhine",
                    selected: false,
                  },
                  {
                    id: 2,
                    name: "Amrita Rabi",
                    selected: false,
                  },
                  {
                    id: 3,
                    name: "Ruza Alannah",
                    selected: false,
                  },
                ]
              },
              computed: {
                allSelected: {
                  set (selected) {
                    this.users.forEach(function (user) {
                      user.selected = selected;
                    });
                  },
                  get () {
                    return this.users.every(function (user) {
                      return user.selected;
                    });
                  }
                }
              },
              methods: {
                getSelectedUsers () {
                  let users = this.users.filter((user) => {
                    return user.selected;
                  });
                  
                  console.log(users);
                }
              }
            })
            

            请注意,您需要属性 user.selected 从一开始就存在(例如,如果您从 API 或其他地方加载数据)。

            工作示例:https://jsfiddle.net/y8gujf2p/

            【讨论】:

              猜你喜欢
              • 2020-03-29
              • 2013-02-02
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多