uniapp下單選框的實現(xiàn)方法詳解
uniapp官方雖然提供了uni-data-checkbox
,含括了單選和多選框功能。但是它功能實在不能滿足需求:
- 單選框不支持再次點擊取消
- 無法與父組件的數(shù)據(jù)源進行聯(lián)動,無法實現(xiàn)如多規(guī)格選擇的那種聯(lián)動
- 源碼每次點擊都是對數(shù)據(jù)源進行拷貝,然后再進行json解析等操作,看著就很不靠譜,數(shù)據(jù)量大必然有性能問題。
其實我放棄uni-data-checkbox
,選擇自己實現(xiàn)也是因為商品規(guī)格展示是比較復雜的,不自己實現(xiàn)的話無法達到目的:
看圖中,三組規(guī)格選項是要相互聯(lián)動的,選擇了其中一個后,就得判斷其余的是否可選。然后我認為也可以將已選中的取消。所以得自己實現(xiàn),好根據(jù)業(yè)務定制。
代碼如下:
<template> <!-- uniapp內置的單選組件,見https://uniapp.dcloud.io/component/radio.html --> <radio-group class="checklist-group" @change="change"> <label class="checklist-box is--tag" v-for="item in radioData.option" :class="[radioData.selected === item.id ? 'is-checked' : '', item.disable ? 'is-disable' : '']"> <radio class="hidden" :disabled="item.disable" :value="String(item.id)" :checked="radioData.selected === item.id" /> <view class="checklist-content"> <text class="checklist-text">{{ item.text }}</text> </view> </label> </radio-group> </template> <script setup lang="ts"> const props = defineProps({ // 該id設計的目的是為了應對數(shù)組,記錄數(shù)組的下標,這樣父類就不需要遍歷查找了。當然也可以根據(jù)業(yè)務用于其他方面,不需要就不用即可。 id: { type: [Number, String], }, /*數(shù)據(jù)源,它的數(shù)據(jù)結構應該:{selected:,option:[{id:,disable:,text:,}...]} 其中selected 的值應取自option的id。 */ radioData: { type: Object, required: true, }, }); // 點擊后回調父類的change方法 const emit = defineEmits(["change"]); // 點擊后觸發(fā) function change(e: any) { // 參數(shù):tag的id;props.id emit("change", e.detail.value, props.id); } </script> <style lang="scss"> $checked-color: #2979ff; $border-color: #dcdfe6; $disable: 0.4; @mixin flex { /* #ifndef APP-NVUE */ display: flex; /* #endif */ } .checklist-group { @include flex; flex-direction: row; flex-wrap: wrap; .checklist-box { @include flex; flex-direction: row; align-items: center; position: relative; margin: 5px 0; margin-right: 25px; .hidden { position: absolute; opacity: 0; } // 文字樣式 .checklist-content { @include flex; flex: 1; flex-direction: row; align-items: center; justify-content: space-between; .checklist-text { font-size: 14px; color: #666; margin-left: 5px; line-height: 14px; } } // 單選樣式 .radio__inner { @include flex; /* #ifndef APP-NVUE */ flex-shrink: 0; box-sizing: border-box; /* #endif */ justify-content: center; align-items: center; position: relative; width: 16px; height: 16px; border: 1px solid $border-color; border-radius: 16px; background-color: #fff; z-index: 1; .radio__inner-icon { width: 8px; height: 8px; border-radius: 10px; opacity: 0; } } // 標簽樣式 &.is--tag { margin-right: 10px; padding: 5px 10px; border: 1px $border-color solid; border-radius: 3px; background-color: #f5f5f5; .checklist-text { margin: 0; color: #666; } // 禁用 &.is-disable { /* #ifdef H5 */ cursor: not-allowed; /* #endif */ opacity: $disable; } &.is-checked { background-color: $checked-color; border-color: $checked-color; .checklist-text { color: #fff; } } } } } </style>
其實代碼本身內容很少,是樣式的代碼多,我樣式是直接照抄uni-data-checkbox
的。
傳入的數(shù)據(jù)結構應該是:
interface radio{ selected: number; option: { id: number; text: string; disable: boolean; }[]; }
selected
和id
可以是別的類型,但selected
是取值于id
這里得注意,數(shù)據(jù)源必須是響應式的,考慮這里肯定是個對象,那么就是要用reactive
去包圍數(shù)據(jù),使其具有響應性,否則頁面不會更新,例如下面:
const radioData= reactive(radio);
PS1:由于vue3規(guī)范建議:子組件不修改父組件的數(shù)據(jù)源,否則會導致數(shù)據(jù)的變化難以理解。所以change方法中沒有做任何修改數(shù)據(jù)的動作。比如將selected直接修改也是完全可以的,但是我這里還是交由父組件去決定如何修改。
PS2:咋一看change方法僅傳遞了當前選擇的選項,并沒有告知之前的選項是什么,如果要對比前后的時候不是沒有辦法?其實selected就是存儲的之前的選項,在修改它之前用它作比較即可。
PS3:由于radio本身是不支持選中之后再取消的,我們這里采用將selected
賦值為一個不存在的id,這樣就會取消選擇了。但是會報錯:
uni-shared.es.js:470 Uncaught TypeError: Cannot destructure property 'id' of 'el' as it is null. at normalizeTarget (uni-shared.es.js:470:13) at createNativeEvent (uni-h5.es.js:1260:13) at $nne (uni-h5.es.js:1234:15) at HTMLElement.invoker (vue.runtime.esm.js:9397:19)
但是不影響功能哈。
PS4:目前僅在H5下測試功能時正常的。
總結
到此這篇關于uniapp下單選框實現(xiàn)的文章就介紹到這了,更多相關uniapp下單選框實現(xiàn)內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
javascript消除window.close()的提示窗口
有人問起,怎么去掉js調用window.close()時怎么去掉那可惡的提示,咋一看好像還真不好弄,IE的安全機制好像就不允許通過腳本關閉本頁面,但是IE好像可以允許js關閉彈出窗口,那我們是不是可以通過一定的技巧欺騙一下IE,繞過去呢。鼓搗了幾下,似乎還真可以做到2015-05-05javascript實現(xiàn)數(shù)組最大值和最小值的6種方法
比較數(shù)組中數(shù)值的大小是比較常見的操作,本文主要介紹了javascript實現(xiàn)數(shù)組最大值和最小值的6種方法,需要的朋友們下面隨著小編來一起學習學習吧2021-05-05JavaScript中對循環(huán)語句的優(yōu)化技巧深入探討
這篇文章主要介紹了JavaScript中對循環(huán)語句的優(yōu)化技巧深入探討,本文翻譯自一個臺灣朋友的文章,需要的朋友可以參考下2014-06-06JavaScript關于prototype實例詳解(超重點)
prototype是js里面給類增加功能擴展的一種模式,這篇文章主要介紹了JavaScript關于prototype(超重點),本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-08-08