选中所有复选框vuejs

时间:2015-11-06 16:32:02

标签: javascript checkbox

我在表格中显示用户列表,每行都有一个复选框来选择用户,复选框值是用户的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() {
            // ?
        }
    }
})

10 个答案:

答案 0 :(得分:38)

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

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

&#13;
&#13;
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;
            }
        }
    }
});
&#13;
<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>
&#13;
&#13;
&#13;

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

答案 1 :(得分:5)

添加我自己的答案作为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/

答案 2 :(得分:5)

我的答案如何,属性较少,易于理解?

&#13;
&#13;
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;
    },

  }
});
&#13;
<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>
&#13;
&#13;
&#13;

答案 3 :(得分:3)

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

这是代码:

&#13;
&#13;
// 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
    }
})
&#13;
<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>
&#13;
&#13;
&#13;

答案 4 :(得分:2)

与@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;

          this.users.forEach((user) => {
            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) return;
          });

          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>

答案 5 :(得分:1)

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

Optional(["-r", "/Users/username\n/Library/Application Support/AddressBook", " ", "/Users/username\n/Desktop/test/"])

Running JSFiddle

答案 6 :(得分:1)

通常不需要在表格下方显示选定的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
    }
})

答案 7 :(得分:0)

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

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

答案 8 :(得分:0)

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

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

答案 9 :(得分:0)

这是仅使用 v模型计算的最简单解决方案。无需其他数组,@ click,已选中

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/