Uniapp實現多選下拉框

文章目錄

  • 前言
  • 一、效果展示
    • 1.1 下拉效果圖
    • 1.2 下拉選擇效果圖
    • 1.3 選擇顯示效果圖
  • 二、組件源碼
    • 2.1.CustomCheckbox.vue源碼
    • 2.2.niceui-popup-select.vue源碼
  • 三、demo.vue代碼演示


前言

之前在使用Uniapp時,一直都是下拉框單選。今天某個項目需求需要使用Uniapp實現下拉框多選效果。由于Uniapp自身沒有這個功能,因此只能在插件市場選擇一個別人封裝好的插件,我選擇的是niceui-popup-select下拉選擇器(支持多選)。可能是我下載的版本問題,實現效果不太滿足我們的需求,因此對該插件源碼進行修改調整。


一、效果展示

修改后支持動態配置下拉顯示字段和選擇完成后的顯示列表效果

1.1 下拉效果圖

在這里插入圖片描述

1.2 下拉選擇效果圖

在這里插入圖片描述

1.3 選擇顯示效果圖

在這里插入圖片描述

二、組件源碼

將核心組件代碼CustomCheckbox.vue、niceui-popup-select.vue放到components文件下,如果沒有components,可以按照圖結構進行目錄場景
在這里插入圖片描述

2.1.CustomCheckbox.vue源碼

<template><view class="custom-checkbox" :class="[{'is-checked': isChecked}]" @click="toggle" :style="[labelStyle]"><input type="checkbox" :checked="isChecked" @change="onChange" /><text class="checkmark" :style="[circleStyle]"></text><text class="serve-info">{{label}}</text></view>
</template><script>
export default {props: {value: Boolean,disabled: {type: Boolean,default: false},label:{type:[String,Number],default:''},fontSize:{type:String,default:''},color:{type:String,default:''},circleSize:{type:String,default:''},circleColor:{type: String,default:""}},computed: {isChecked: {get() {return this.value;},set(val) {this.$emit('input', val);}},labelStyle() {let styles = {}if (this.fontSize) {styles.fontSize = this.fontSize}if (this.color) {styles.color = this.color}return styles;},circleStyle(){let styles = {}if (this.circleSize) {styles.transform = this.circleSize}if (this.circleColor) {if(this.isChecked){styles.backgroundColor = this.circleColor}}return styles;}},methods: {toggle() {if (!this.disabled) {this.isChecked = !this.isChecked;this.$emit('toggle', !this.isChecked);}},onChange(event) {this.$emit('change', event.target.checked);}}
};
</script><style scoped lang="scss">
.custom-checkbox {display: flex;align-items: center;position: relative;padding-left: 1rpx;margin-bottom: 0rpx;cursor: pointer;font-size: 32rpx;-webkit-user-select: none;-moz-user-select: none;-ms-user-select: none;user-select: none;margin: 35rpx 0;
}.custom-checkbox input {position: absolute;opacity: 0;cursor: pointer;height: 0;width: 0;
}.checkmark {position: absolute;top:1rpx;margin-bottom:0rpx;right: 0;height: 40rpx;width: 40rpx;/* background-color: #eee; */border:solid 1rpx #ddd;border-radius: 50%;
}.custom-checkbox:hover input .checkmark {background-color: #ccc;
}.custom-checkbox input:checked .checkmark {background-color: blue;
}.checkmark:after {content: "";position: absolute;display: none;
}.custom-checkbox input:checked .checkmark:after {display: block;
}.custom-checkbox .checkmark:after {left: 13rpx;top: 6rpx;width: 12rpx;height: 19rpx;border: solid white;border-width: 0 5rpx 5rpx 0;-webkit-transform: rotate(45deg);-ms-transform: rotate(45deg);transform: rotate(45deg);
}.is-checked .checkmark {background-color: blue;border:solid 0rpx #ddd;
}.is-checked .checkmark:after {display: block;
}.big-area{width: 160rpx;height: 220rpx;position: absolute;z-index:10;top: -155rpx;left: -85rpx;
}
.checkbox-all{margin-top: 160rpx;margin-left: 63rpx;
}
</style>

2.2.niceui-popup-select.vue源碼

<template><uni-popup ref="popup" :animation="false" :isMaskClick="1===0" :maskClick="1===0"><view class="popup-content"><view class="popup-content-main"><view class="picker__toolbar justify-between"><view class="picker__cancel" @click="cancel">取消</view><view class="picker__confirm" @click="onConfirm">確認</view></view><scroll-view class="picker__content" scroll-y="true"><view class="uni-list" v-if="multiple"><custom-checkbox v-model="checkedAll" label="全選" @toggle="toggleAll"fontSize="36rpx" circleSize="scale(1.2)" :color="color" :circleColor="circleColor"/></view><view class="uni-list" v-if="multiple"><template v-if="columnsData.length>0"><custom-checkbox v-model="item.checked" :label="item[option.label]" @toggle="toggleIt($event,item,index)" v-for="(item,index) in columnsData" :key="item[option.value]":fontSize="labelFontSize" :circleSize="circleSize" :color="color" :circleColor="circleColor"/></template><template v-else><view class="no__data">{{noData}}</view></template></view><view class="uni-list" v-else><template v-if="columnsData.length>0"><custom-checkbox v-model="item.checked" :label="item[option.label]" @toggle="toggleIt($event,item,index)" v-for="(item,index) in columnsData" :key="item[option.value]":fontSize="labelFontSize" :circleSize="circleSize" :color="color" :circleColor="circleColor"/></template><template v-else><view class="no__data">{{noData}}</view></template></view>	</scroll-view></view></view></uni-popup>
</template><script>
import CustomCheckbox from './CustomCheckbox.vue'
export default {name: 'NiceuiPopupSelect',components:{CustomCheckbox},props: {columns: {type: Array,default: function () {return []}},selectValue: {type: Array,default: function () {return []}},option: {type: Object,default: function () {return { label: 'label', value: 'value'}}},multiple: {type: Boolean,default: true},labelFontSize:{type: String,default:"32rpx"},color:{type: String,default:"#333"},circleSize:{type: String,default:"scale(1)"},circleColor:{type: String,default:"#004aff"}},data () {return {searchKey: '',columnsData: [],checkedValue:[],checkedAll: false,resultValue:[],noData:'沒有更多內容了',value:false}},methods: {getData (val) {const res = this.columnsData?.filter(item => {return val.indexOf(item[this.option.value]) > -1})return res},onConfirm () {const ck = this.columnsData.filter(d=>d.checked==true)const ids = ck.map(d=>d.id)this.$emit('confirm', ids, this.getData(ids))},cancel () {this.closePopup()},showPopup(){this.columnsData = JSON.parse(JSON.stringify(this.columns))this.columnsData.forEach(d=>d.checked=false)this.checkedValue = JSON.parse(JSON.stringify(this.selectValue))if(this.checkedValue&&this.checkedValue.length>0){this.columnsData.forEach(d=>{if(this.checkedValue.includes(d.id)){d.checked = true}})if(this.checkedValue.length!=this.columnsData.length){this.checkedAll = false}else{this.checkedAll = true}}else{this.checkedAll = false}this.$refs.popup.open('bottom')},closePopup(){this.$refs.popup.close()},toggleIt(v,item,index){if(this.multiple){item.checked= vthis.$set(this.columnsData,index,item)if(!v){this.checkedAll = false}else{const ck = this.columnsData.filter(d=>d.checked===false)if(ck.length===0){this.checkedAll = true}}}else{this.columnsData.forEach(d=>d.checked=false)item.checked=truethis.$set(this.columnsData,index,item)}},toggleAll (v) {this.checkedAll = vif(this.checkedAll){this.columnsData.forEach(d=>d.checked=true)}else{this.columnsData.forEach(d=>d.checked=false)}},}
}
</script><style lang="scss" scoped>//結果彈窗::v-deep .close-view{height: 130rpx;image{width: 100rpx;height: 100rpx;}}::v-deep .popup-content{border-top-left-radius: 20rpx;border-top-right-radius: 20rpx;background-color: #fff;padding: 1rpx;width: 100vw;// height: 70vh;// overflow-y: scroll;.popup-content-main{margin: 50rpx auto 30rpx;.picker__toolbar{box-sizing: border-box;margin:20rpx 32rpx;font-size:$uni-font-size-lg;display: flex;align-items: center;.picker__cancel{width: 70px;height: 25px;border: none;text-align: center;border-radius: 5px;color: #fff;font-size: 18px;background-color: #7c9f33;box-shadow: 0 5px 0 #3a2e38;cursor: pointer;outline: none;}.picker__confirm{margin-left: 20px;width: 70px;height: 25px;border: none;text-align: center;border-radius: 5px;color: #fff;font-size: 18px;background-color: #f30a72;box-shadow: 0 5px 0 #3a2e38;cursor: pointer;outline: none;}.picker__title{font-size: 38rpx;color:#6f6f6f;}}.picker__content{max-height:500rpx;overflow-y:auto;.keyword-input{font-size: 35rpx;}.check__all{box-sizing: border-box;margin:20rpx 23rpx 20rpx 32rpx;padding:20rpx 0rpx;border-bottom:solid 1rpx #f7f7f7;display: flex;justify-content: space-between;.check__all_left{color:#666;font-size: 32rpx;}.check__all_right{}}.uni-list{box-sizing: border-box;margin:20rpx 32rpx;label{padding:20rpx 0rpx;border-bottom:solid 1rpx #f7f7f7;}.uni-list-cell{.cell-label{font-size: 35rpx;}checkbox{//transform:scale(0.8,0.8)}}.no__data{color:#999;font-size: 30rpx;text-align: center;margin-top: 50rpx;}}}}}.bottom-line{border-bottom: solid 3rpx #eee;margin:20rpx 32rpx;height: 72rpx;}
</style>

三、demo.vue代碼演示

demo代碼演示了如何使用組件實現自己想要的下拉效果,直接復制運行即可實現章節一的展示效果

<template><view class="content"><view class="uni-list-cell"><view class="uni-list-cell-left">選擇</view><view class="uni-list-cell-db"><view class="as-input" @click="openSelectPopup"><view class="placeholder" v-if="checkedDynamicComputed===undefined||checkedDynamicComputed===''">請選擇</view><view class="as-content" v-else>{{checkedDynamicComputed}}</view><uni-icons type="forward" size="16" color="#c0c4cc" class="customer-icon"></uni-icons></view></view></view><niceui-popup-select ref="showFruit" :columns="selectList" :selectValue="checkedResult" :is-search="false" :option="{label:selectLabel, value:selectKey}" @confirm="confirmCheck"/></view>
</template><script>
import NiceuiPopupSelect from '@/components/popupSelect/niceui-popup-select/niceui-popup-select.vue'
export default {components:{NiceuiPopupSelect},data() {return {selectLabel:"code",//下拉框選項顯示時,顯示指定字段的值selectKey:"id",//下拉框選擇時,選中后獲取的字段值selectList:[{id:1,code:'西瓜',},{id:2,code:'香蕉'},{id:3,code:'桃子'},{id:4,code:'蘋果2'},],checkedResult:[],checkedLabels:[],}},computed:{checkedDynamicComputed(){return this.checkedLabels.join(",");},},methods: {openSelectPopup(){this.$refs.showFruit.showPopup()},/**** @param selectKeysValues 選中中的selectKey列的值集合* @param data  選中多行數據的集合*/confirmCheck(selectKeysValues,data) {this.checkedResult = selectKeysValuesthis.checkedLabels=[];//清除原始內容data.map(item=>{//對顯示內容進行處理,可以進行多個字段進行拼接// this.checkedLabels.push(item[this.selectLabel]+"_"+item[this.selectKey])//可以指定將某字段作為顯示值this.checkedLabels.push(item[this.selectLabel])})this.$refs.showFruit.closePopup()},}
}
</script><style lang="scss" scoped>
.content{background-color: #f7f7f7;width: 100vw;height: 100vh;}
.uni-title{font-size: 33rpx;font-weight: bold;padding: 20rpx 20rpx;
}
.uni-list-cell{background-color: #fff;display: flex;justify-content: space-between;align-items: center;padding: 20rpx 20rpx;.uni-list-cell-left{font-size: 35rpx;}
}
.uni-list-cell-db{flex:1
}
.as-input{width: 100%;display: flex;align-items: center;justify-content: flex-end;.customer-icon{padding: 0 0 0 5rpx;}.placeholder{font-size:33rpx;color:#999;}.as-content{color: #333;font-size: 33rpx;width: 370rpx;text-align: right;}
}
</style>

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/83352.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/83352.shtml
英文地址,請注明出處:http://en.pswp.cn/web/83352.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

JavaScript-Array.from

Array.from() 是 JavaScript 中用于將類數組對象&#xff08;array-like&#xff09;或可迭代對象&#xff08;iterable&#xff09;轉換為真實數組的一個非常有用的方法。 &#x1f4cc; 一、基本語法 Array.from(arrayLike, mapFn?, thisArg?)參數說明&#xff1a; 參數類…

二刷蒼穹外賣 day02

新增員工 DTO 將前端傳遞的參數列表通過對應的實體類接收 當前端提交的數據和實體類中對應的屬性差別較大時&#xff0c;使用DTO來封裝數據 Data public class EmployeeDTO implements Serializable {private Long id;private String username;private String name;private…

通過Heron Handoff 插件我們在figma設計中可以像sketch導出離線標注

一、設計交付的歷史困境與破局契機 在數字產品開發的全流程中&#xff0c;設計標注的高效傳遞始終是連接創意與實現的關鍵紐帶。傳統設計工具如 Sketch 憑借 Bluebeam、Sketch Measure 等插件構建了成熟的離線標注體系&#xff0c;設計師可將標注文件打包交付&#xff0c;開發…

SSE 數據的傳輸無法流式獲取

問題 調試過程中發現SSE數據返回的時間都是一樣的&#xff0c;懷疑是接口問題。 參考 EventSource數據一次性出來&#xff0c;并未流式輸出的原因_sourceevent為什么結果一下全部返回了-CSDN博客 處理 EventStream 不能流式返回的問題&#xff1a;Nginx 配置優化 解決方案 …

markdown文本轉換時序圖

好久沒更新了~這篇是markdown文本轉換時序圖的常用方法 文章目錄 前言一、Mermaid語法示例二、PlantUML語法示例三、在線工具快速轉換總結 前言 使用專業工具如Mermaid或PlantUML可以直接在Markdown中繪制時序圖。這些工具支持簡潔的語法&#xff0c;生成可嵌入文檔的圖表&…

谷粒商城-分布式微服務 -集群部署篇[一]

十九、k8s 集群部署 19.1 k8s 快速入門 19.1.1 簡介 Kubernetes 簡稱 k8s。是用于自動部署&#xff0c;擴展和管理容器化應用程序的開源系統。 中文官網 中文社區 官方文檔 社區文檔 概述 | Kubernetes 傳統部署時代&#xff1a; 早期&#xff0c;各個組織是在物理服務器上…

微信小程序- 用canvas生成排行榜

設計功能不是很復雜&#xff0c;也不想用插件&#xff0c;最終出現現在版本&#xff0c;主要用到微信小程序 wx.canvasToTempFilePath方法 // 直接調用改方法 createQRCode() {const qrCodeCanvasId "qrcodeCanvas";drawQrcode({width: 200,height: 200,canvasId: …

深度剖析:UI 設計怎樣為小程序構建極致輕量體驗

內容摘要 在小程序的世界里&#xff0c;用戶都追求快速、便捷的輕量體驗。但你是否好奇&#xff0c;為啥有些小程序能讓人輕松上手&#xff0c;快速達成目標&#xff0c;而有些卻讓人感覺繁瑣、卡頓&#xff1f;這里的關鍵差異&#xff0c;往往就藏在 UI 設計中。UI 設計到底施…

【網絡安全】Qt免殺樣本分析

初步研判 SHA256&#xff1a;9090807bfc569bc8dd42941841e296745e8eb18b208942b3c826b42b97ea67ff 我們可以看到引擎0檢出&#xff0c;是個免殺樣本&#xff0c;不過通過微步云沙箱的行為分析&#xff0c;已經被判為惡意 行為分析 進程行為 可以看到demo顯示調用了winver獲…

window 顯示驅動開發-如何查詢視頻處理功能(六)

D3DDDICAPS_FILTERPROPERTYRANGE請求類型 UMD 返回指向 DXVADDI_VALUERANGE 結構的指針&#xff0c;該結構包含傳遞D3DDDICAPS_FILTERPROPERTYRANGE請求類型時特定視頻流上特定篩選器設置允許的值范圍。 Direct3D 運行時在D3DDDIARG_GETCAPS的 pInfo 成員指向的變量中為特定視…

Oracle線上故障問題解決

----重啟電腦找不到sid Listener refused the connection with the following error: ORA-12505, TNS:listener does not currently know of SID given in connect descriptor Could not open connection sqlplus "/as sysdba" SQL> shutdown immediate 數據庫…

語音信號處理三十——高效多相抽取器(Polyphase+Noble)

文章目錄 前言一、Polyphase 多項分解1.定義2.拆分公式3.推導過程1&#xff09;按模 M M M拆分求和項2&#xff09;提取因子 4.總結 二、Noble恒等式1. 定義2.Noble恒等式表達方式1&#xff09;抽取系統的 Noble 恒等式2&#xff09;插值系統的 Noble 恒等式 2.Nodble恒等式推導…

廣告推薦系統中模型訓練中模型的結構信息、Dense數據、Sparse數據

下面結合廣告推薦系統常見的深度學習模型(比如 Wide & Deep、DeepFM、Two-Tower 等),介紹一下“模型的結構信息”、Dense 數據和 Sparse 數據在訓練過程中的角色及處理方式。 模型結構信息 輸入層(Input Layer) ? Sparse 輸入:各類離散高維特征(用戶 ID、廣告 ID、…

安全生產管理是什么?安全生產管理主要管什么?

安全生產管理是什么&#xff1f;安全生產管理主要管什么&#xff1f; 不管是制造業、建筑業&#xff0c;還是倉儲、物流、化工等等&#xff0c;一聊到“安全事故”&#xff0c;大家腦子里最先冒出來的兩個詞&#xff0c;肯定就是&#xff1a; 人的不安全行為物的不安全狀態 …

SecureRandom.getInstanceStrong() 與虛擬機的愛恨情仇

問題描述 使用Ruoyi-cloud 二開&#xff0c;將服務部署到虛擬機上后&#xff0c;準備登錄&#xff0c;發現驗證碼一致加載不出來&#xff0c;接口請求超時! 解決步驟 telnet 虛擬機ipport 發現可以通.curl 接口&#xff0c;發現一致不返回&#xff0c;超時了./code 接口超時&am…

DEM 地形分析與水文建模:基于 ArcGIS 的流域特征提取

技術點目錄 一、 GIS理論及ArcGIS認識二、ArcGIS數據管理與轉換三、ArcGIS地圖制作與發布四、ArcGIS數據制備與編輯五、ArcGIS矢量空間分析及應用六、ArcGIS柵格空間分析及應用七、ArcGIS空間插值及應用八、DEM數據與GIS三維分析九、ArcGIS高級建模及應用十、綜合講解了解更多 …

芯伯樂XBLW GT712選型及應用設計指南

前言 在電子工程領域&#xff0c;精準的電流測量對于眾多電路設計與系統監控至關重要。芯伯樂推出的XBLW GT712電流傳感器以其獨特的優勢&#xff0c;成為工程師在諸多應用中的首選工具。本文將深入剖析XBLW GT712的工作原理、性能特點以及應用要點&#xff0c;為工程師提供詳…

MySQL查看連接情況

說明&#xff1a;本文介紹如何查看MySQL會話連接情況&#xff0c;方便排查MySQL占用CPU過高或其他問題。 連接數據庫 首先&#xff0c;使用命令行連接到MySQL數據庫 mysql -u[用戶名] -p[密碼] -h[主機IP] -P[端口號]如果MySQL就在本機上&#xff0c;那么如下即可 mysql -u…

圖文教程——Deepseek最強平替工具免費申請教程——國內edu郵箱可用

親測有效&#xff01;只需 4 步即可免費體驗最新最強的 AI 助手&#xff01; 最強AI助手 This account isn’t eligible for Google AI Pro plan Google AI Pro plan isn’t available in some countries or for people under a certain age. 問題終極解決方案&#xff1a; ht…

java轉PHP開發需要幾步?

PHP基礎入門指南&#xff08;面向Java開發者&#xff09; 作為Java開發者&#xff0c;你已經掌握了面向對象編程、變量類型和控制結構等核心概念&#xff0c;這將大大加速你學習PHP的過程。下面我將從語法差異和PHP特性兩個方面&#xff0c;幫助你快速上手PHP開發。 語法差異…