本篇文章給大家?guī)砹岁P(guān)于uniapp的相關(guān)知識(shí),其中主要整理了實(shí)現(xiàn)多選框的全選功能的相關(guān)問題,無法實(shí)現(xiàn)全選的原因是動(dòng)態(tài)修改checkbox的checked字段時(shí),界面上的狀態(tài)能夠?qū)崟r(shí)變化,但是無法觸發(fā)checkbox-group的change事件,下面一起來看一下,希望對(duì)大家有幫助。
推薦:《uniapp教程》
uniapp內(nèi)置的checkbox
其實(shí)以及checkbox-group
本來挺好的,但是有兩個(gè)問題:
- 無法依賴其事件實(shí)現(xiàn)全選
- 樣式固定,難以修改
他們無法實(shí)現(xiàn)全選的原因是:
我動(dòng)態(tài)修改checkbox
的checked
字段時(shí),界面上的狀態(tài)能夠?qū)崟r(shí)變化,但是無法觸發(fā)checkbox-group
的change
事件。意味著無法依賴checkbox-group
管理好已選項(xiàng)。
就是說:我點(diǎn)了全選,界面上看著是全選了。然后此時(shí)我取消了其中一個(gè)選項(xiàng),此時(shí)觸發(fā)change事件,但是它反饋給我的已選列表是錯(cuò)的。這是不行的。
所以我自己想了個(gè)實(shí)現(xiàn)全選多選框的方案。
實(shí)現(xiàn)思路
鑒于上面的問題,于是就可以放棄checkbox-group
了,那么,我順便就放棄了checkbox
,因?yàn)槲腋矚gradio的圓圈樣式。
首先先模擬生成一些數(shù)據(jù),方便展示,數(shù)據(jù)的要點(diǎn)是要有一個(gè)字段selected
,其余隨心所欲:
<script setup lang="ts"> import { reactive } from "vue"; // 模擬的數(shù)據(jù)對(duì)象,要是響應(yīng)式的 let data = reactive([] as { id: number; text: string; selected: boolean }[]); // 生成數(shù)據(jù) for (let i = 0; i < 10; i++) { data.push({ id: i + 5, text: "標(biāo)題" + i, selected: false, }); }</script>
然后我們需要有一個(gè)存儲(chǔ)已選擇數(shù)據(jù)信息的對(duì)象,采用map:
// 存儲(chǔ)已選內(nèi)容, 因?yàn)檫@個(gè)列表是增刪很頻繁的,所以選用map而不是數(shù)組,key對(duì)應(yīng)的是數(shù)據(jù)的下標(biāo)。至于value存放什么,完全由自己定 let selected = reactive(new Map<number, number>());
在然后我們得有一個(gè)選項(xiàng)框點(diǎn)擊事件,用于選擇數(shù)據(jù)或者取消選擇:
// 選項(xiàng)框點(diǎn)擊事件,參數(shù)是數(shù)據(jù)的下標(biāo) function checkbox(index: number) { // 選中的狀態(tài)下再次點(diǎn)擊,即為取消選中 if (data[index].selected) { data[index].selected = false; selected.delete(index); // 然后刪除對(duì)應(yīng)key即可 } // 未選中狀態(tài)下點(diǎn)擊 else { data[index].selected = true; selected.set(index, data[index].id); } }
再再然后,我們還得有一個(gè)全選的點(diǎn)擊事件:
// 全選與反選事件 function allSelect() { // 已經(jīng)全選情況下,就是反選,全選就說明長(zhǎng)度一樣 if (selected.size === data.length) { selected.clear(); // 全部清除 data.forEach((element) => { element.selected = false; // 全部不選,就行了 }); } // 還未全選的狀態(tài)下 else { data.forEach((element, index) => { // 因?yàn)榭赡艽嬖诓糠忠呀?jīng)選擇了,所以得先判斷是否已存在,不存在才需要添加 if (!selected.has(index)) { selected.set(index, element.id); // key是對(duì)應(yīng)的下標(biāo)index,而value是可以自定義的 element.selected = true; // 設(shè)為選中 } }); } }
其實(shí)上面兩個(gè)點(diǎn)擊事件都是很基本的判斷和增刪數(shù)據(jù)。至此功能已經(jīng)全部都有了,下面看看頁(yè)面怎么寫:
<template> <!-- 是個(gè)多選列表 --> <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>
其實(shí)就兩組radio,一個(gè)是循環(huán)展示數(shù)據(jù),一個(gè)是全選按鈕。
連起來的完整代碼:
<template> <!-- 是個(gè)多選列表 --> <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"; // 模擬的數(shù)據(jù)對(duì)象,要是響應(yīng)式的 let data = reactive([] as { id: number; text: string; selected: boolean }[]); // 生成數(shù)據(jù) for (let i = 0; i < 10; i++) { data.push({ id: i + 5, text: "標(biāo)題" + i, selected: false, }); } // 存儲(chǔ)已選內(nèi)容, 因?yàn)檫@個(gè)列表是增刪很頻繁的,所以選用map而不是數(shù)組,key對(duì)應(yīng)的是數(shù)據(jù)的下標(biāo)。至于value存放什么,完全由自己定 let selected = reactive(new Map<number, number>()); // 全選與反選事件 function allSelect() { // 已經(jīng)全選情況下,就是反選,全選就說明長(zhǎng)度一樣 if (selected.size === data.length) { selected.clear(); // 全部清除 data.forEach((element) => { element.selected = false; // 全部不選,就行了 }); } // 還未全選的狀態(tài)下 else { data.forEach((element, index) => { // 因?yàn)榭赡艽嬖诓糠忠呀?jīng)選擇了,所以得先判斷是否已存在,不存在才需要添加 if (!selected.has(index)) { selected.set(index, element.id); // key是對(duì)應(yīng)的下標(biāo)index,而value是可以自定義的 element.selected = true; // 設(shè)為選中 } }); } } // 選項(xiàng)框點(diǎn)擊事件,參數(shù)是數(shù)據(jù)的下標(biāo) function checkbox(index: number) { // 選中的狀態(tài)下再次點(diǎn)擊,即為取消選中 if (data[index].selected) { data[index].selected = false; selected.delete(index); // 然后刪除對(duì)應(yīng)key即可 } // 未選中狀態(tài)下點(diǎn)擊 else { data[index].selected = true; selected.set(index, data[index].id); } }</script><style></style>
看起來代碼不少,其實(shí)都是很基礎(chǔ)的邏輯判斷。
最后效果是這樣的:
全選:
多選:
反選全部:
推薦:《uniapp教程》