文章目录

  • 前言
  • 一、效果展示
    • 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开发。 语法差异…