Vue 實作 check box 全選與取消全選

Vue 實作 check box 全選與取消全選

check box 全選與取消全選有 2 種做法可以實現這個功能,可以使用 methods 來實現,也可以使用 computed 來監聽「全選的核取框」。

使用 methods 方法實作

  • 全選的 check box 雙向綁定到 allChecked 這個資料狀態,預設的布林值為 false。
  • checkList 這個資料狀態是一個陣列,存放所有的 check box 選項。
  • 在 data 中準備一個 checkedItems 的空陣列。
  • 使用 v-for 把 checkList 裡面的資料渲染成一個一個的 check box 選項,與 checkedItems 雙向綁定。
  • methods 中,準備一個 allCheckedFn 的方法,綁定change事件到「全選」的核取框,把 checkList 裡面的的選項 map 到一個 arr 空陣列,點擊全選的時候,allChecked會變成 true ,然後使用 三元運算式判斷,當 allChecked 為 true 的時候,checkedItems(與所有選項雙向綁定)會被賦值為 arr ,allChecked 為 false 的時候為空陣列:
    this.checkedHeros = this.allChecked ? arr : [];
  • changeFn這個方法,比對 checkedHeros 的陣列長度與 核取框原始資料陣列長度 是否一致,返回一個布林值,賦值給 全選 allChecked 這個資料狀態。
<div id="app">
  <p>
    <input type="checkbox" id="select" v-model="allChecked" @change="allCheckedFn">
    <label for="select">全選/反選</label>
  </p>
  <!-- 注意下面 input 對應的都是 v-model="checkedHeros"  -->
  <div v-for="item in checkList" :key="item.id" v-model="checkedItems"> 
    <input type="checkbox" id="item.name" :value="item.name" v-model="checkedItems" @change="changeFn">
    <label for="item.name">{{item.id + item.name}}</label>
  </div>

  <br>
  <p>checkedItems: {{ checkedItems }}</p>
</div>
// 因為是複選的關係,這裡的 checkedHeros 是陣列
const vm = Vue.createApp({
  data () {
    return {
      // checkedHeros和複選框雙向綁定
      checkedItems: [],
      allChecked: false,
      checkList:[{
        name:'鋼鐵人',
        id:1,        
      },{
         name:'蜘蛛人',
        id:2,
      },{
         name:'蟻人',
        id:3,
      }]
    }
  },
  methods:{
    // 全選用的方法
    allCheckedFn(){
      let arr=[];
      // heroList 是所有選項的清單,arr 這個陣列會裝進所有選項
      this.checkList.map(item=>{
        return arr.push(item.name);        
      })
      // allChecked 和全選框綁定,如果是true,就是裝有所有選項的 arr 陣列(全選),如果 false ,就是空陣列(全不選)
      this.checkedItems = this.allChecked ? arr : [];
    },
    changeFn(){
//       比對
      this.allChecked = this.checkedItems.length == this.checkList.length;
      console.log(this.allChecked);
    }
  }
})

vm.mount('#app');

使用 computed 實作

使用 computed 監聽 allChecked 這個資料狀態,然後 allChecked 與全選框綁定。checkedItems 與所有的選項雙向綁定。

  • get 的部分是監聽所有的選項,所有選項都打勾時,全選會被核取。
    • 使用三元運算子,當 checkList 的陣列長度等於 checkedItems 的陣列長度時,全選會打勾。
  • set 的部分是監聽全選框,全選核取時,所有的選項都會打勾。
    • 設一個 selected 空陣列,當全選框勾選時,value 為 true,會把 checkList 裡的選項推到 selected,把 selected 賦值給 checkedItems,這時所有選項都會打勾。
    • 當全選框沒有勾選時, value 為 false,selected 為空陣列,checkedItems 裏沒有選項。
      <div id="app">
        <p>
          <input type="checkbox" id="select" v-model="allChecked">
          <label for="select">全選/反選</label>
        </p>
        <!-- 注意下面 input 對應的都是 v-model="checkedHeros"  -->
        <div v-for="item in checkList" :key="item.id" > 
          <input type="checkbox" id="item.name" :value="item.name" v-model="checkedItems">
          <label for="item.name">{{item.id + item.name}}</label>
        </div>
      
        <br>
        <p>Checked heros: {{ checkedItems }}</p>
      </div>
// 因為是複選的關係,這裡的 checkedHeros 是陣列
const vm = Vue.createApp({
  data() {
    return {
      checkedHeros: [],
      // allChecked: false,
      heroList: [
        {
          name: "鋼鐵人",
          id: 1,
          selected: false
        },
        {
          name: "蜘蛛人",
          id: 2,
          selected: false
        },
        {
          name: "蟻人",
          id: 3,
          selected: false
        }
      ]
    };
  },
  computed: {
    //allChecked 與 全選雙向綁定
    allChecked: {
      //當所有選項都選的時候,全選會打勾
      get: function () {
        return this.heroList
          ? this.checkedHeros.length === this.heroList.length
          : false;
      },
      //全選打勾時,所有選項都會打勾
      set: function (value) {
        // value 是  在全選 checkbox 上的勾選狀態,打勾時為 true,用 v-model 雙向綁定
        // 暫存用陣列,用來存放被打勾的 checkbox value
        let selected = [];
        // 如果全選打勾
        if (value) {
          // 把可以勾的 選項 push 到暫存的 selected 陣列
          this.heroList.forEach((item) => {
            // 寫入暫存陣列
            selected.push(item.name);
          });
        }
        console.log(selected);
        // 將暫存陣列的值寫到已經勾選的容器陣列,表示全都勾(true),false 時會被清空,因為 selected 此時為空陣列
        this.checkedHeros = selected;
      }
    }
  }
});

vm.mount("#app");

Vue 實作 check box 全選與取消全選
https://popeye-ux.github.io/2023/03/09/vue-allchecked/
作者
POPEYE
發布於
2023年3月9日
許可協議