uniapp多選框全選功能的實現思路與方法實例
前言
uniapp內置的checkbox
其實以及checkbox-group
本來挺好的,但是有兩個問題:
- 無法依賴其事件實現全選
- 樣式固定,難以修改
他們無法實現全選的原因是:
我動態修改checkbox
的checked
字段時,界面上的狀態能夠實時變化,但是無法觸發checkbox-group
的change
事件。意味著無法依賴checkbox-group
管理好已選項。
就是說:我點瞭全選,界面上看著是全選瞭。然後此時我取消瞭其中一個選項,此時觸發change事件,但是它反饋給我的已選列表是錯的。這是不行的。
所以我自己想瞭個實現全選多選框的方案。
實現思路
鑒於上面的問題,於是就可以放棄checkbox-group
瞭,那麼,我順便就放棄瞭checkbox
,因為我更喜歡radio的圓圈樣式。
首先先模擬生成一些數據,方便展示,數據的要點是要有一個字段selected
,其餘隨心所欲:
<script setup lang="ts"> import { reactive } from "vue"; // 模擬的數據對象,要是響應式的 let data = reactive([] as { id: number; text: string; selected: boolean }[]); // 生成數據 for (let i = 0; i < 10; i++) { data.push({ id: i + 5, text: "標題" + i, selected: false, }); } </script>
然後我們需要有一個存儲已選擇數據信息的對象,采用map:
// 存儲已選內容, 因為這個列表是增刪很頻繁的,所以選用map而不是數組,key對應的是數據的下標。至於value存放什麼,完全由自己定 let selected = reactive(new Map<number, number>());
在然後我們得有一個選項框點擊事件,用於選擇數據或者取消選擇:
// 選項框點擊事件,參數是數據的下標 function checkbox(index: number) { // 選中的狀態下再次點擊,即為取消選中 if (data[index].selected) { data[index].selected = false; selected.delete(index); // 然後刪除對應key即可 } // 未選中狀態下點擊 else { data[index].selected = true; selected.set(index, data[index].id); } }
再再然後,我們還得有一個全選的點擊事件:
// 全選與反選事件 function allSelect() { // 已經全選情況下,就是反選,全選就說明長度一樣 if (selected.size === data.length) { selected.clear(); // 全部清除 data.forEach((element) => { element.selected = false; // 全部不選,就行瞭 }); } // 還未全選的狀態下 else { data.forEach((element, index) => { // 因為可能存在部分已經選擇瞭,所以得先判斷是否已存在,不存在才需要添加 if (!selected.has(index)) { selected.set(index, element.id); // key是對應的下標index,而value是可以自定義的 element.selected = true; // 設為選中 } }); } }
其實上面兩個點擊事件都是很基本的判斷和增刪數據。至此功能已經全部都有瞭,下面看看頁面怎麼寫:
<template> <!-- 是個多選列表 --> <view v-for="(item, index) in data"> <label style="margin-left: 50px"> <radio :value="String(index)" :checked="item.selected" @click="checkbox(index)" />{{ item.text }} </label> </view> <!-- 全選按鈕 --> <label> <radio value="1" :checked="selected.size === data.length" @click="allSelect" />全選</label> </template>
其實就兩組radio,一個是循環展示數據,一個是全選按鈕。
連起來的完整代碼:
<template> <!-- 是個多選列表 --> <view v-for="(item, index) in data"> <label style="margin-left: 50px"> <radio :value="String(index)" :checked="item.selected" @click="checkbox(index)" />{{ item.text }} </label> </view> <!-- 全選按鈕 --> <label> <radio value="1" :checked="selected.size === data.length" @click="allSelect" />全選</label> </template> <script setup lang="ts"> import { reactive } from "vue"; // 模擬的數據對象,要是響應式的 let data = reactive([] as { id: number; text: string; selected: boolean }[]); // 生成數據 for (let i = 0; i < 10; i++) { data.push({ id: i + 5, text: "標題" + i, selected: false, }); } // 存儲已選內容, 因為這個列表是增刪很頻繁的,所以選用map而不是數組,key對應的是數據的下標。至於value存放什麼,完全由自己定 let selected = reactive(new Map<number, number>()); // 全選與反選事件 function allSelect() { // 已經全選情況下,就是反選,全選就說明長度一樣 if (selected.size === data.length) { selected.clear(); // 全部清除 data.forEach((element) => { element.selected = false; // 全部不選,就行瞭 }); } // 還未全選的狀態下 else { data.forEach((element, index) => { // 因為可能存在部分已經選擇瞭,所以得先判斷是否已存在,不存在才需要添加 if (!selected.has(index)) { selected.set(index, element.id); // key是對應的下標index,而value是可以自定義的 element.selected = true; // 設為選中 } }); } } // 選項框點擊事件,參數是數據的下標 function checkbox(index: number) { // 選中的狀態下再次點擊,即為取消選中 if (data[index].selected) { data[index].selected = false; selected.delete(index); // 然後刪除對應key即可 } // 未選中狀態下點擊 else { data[index].selected = true; selected.set(index, data[index].id); } } </script> <style></style>
看起來代碼不少,其實都是很基礎的邏輯判斷。
最後效果是這樣的:
全選:
多選:
反選全部:
總結
到此這篇關於uniapp多選框全選功能實現的文章就介紹到這瞭,更多相關uniapp多選框全選功能內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- 微信小程序自定義復選框
- vue項目input標簽checkbox,change和click綁定事件的區別說明
- Vue 實現穿梭框功能的詳細代碼
- 解決Element-ui radio單選框label佈爾/數值的一個坑
- Vue 表單輸入綁定v-model