uniapp 弹出框二次封装

作者分享了自己在Uniapp开发中封装的弹出框组件,包括其传入参数、方法和样式,适合快速上手使用。组件支持单选或多选模式,可方便地集成到项目中并根据需求调整。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

近期一直在做uniapp,所以自己封装了几个组件,是在uniapp提供组件的基础上进行的二次封装,感觉还是挺实用的,先贴个弹出框的,上代码:

/**
 * 弹窗组件 made by jidzh
 *
 * 最后修改时间:2021-03-18
 *
 * 传入参数:
 * filterArray:循环数组
 * title:标题
 * mode:单选(single)、多选(multiple),默认值为single
 * backgroundColor:背景颜色(可传入主题),默认值为#fff
 * width:弹出框宽度,默认值为300px
 * popPosition:弹出框位置,默认值为right
 * currentName:当前选中(single),多选时直接操控multipleIndexes插入选中index
 * 
 * 抛出方法:
 * filterChange:选择后返回选择filterArray下标
 *
 */
<template>
	<uni-drawer :visible="true" ref="draw" :mode="popPosition" :width="width" @change="changeDrawer">
		<view class="filterUl">
			<view class="popHeader" style=" border-bottom: 1px solid #e3e3e5; ">
				<uni-icons type="closeempty" size="26" :color="themeColor" @click="close" />
				<text class="title">{{title}}</text>
			</view>
			<scroll-view scroll-y="true" class="filterBox" :style="{height: mode === 'multiple'?'calc(100% - 91px)':'calc(100% - 51px)'}">
				<view class="filterItem">
					<view class="filterList" v-for="(item,index) in filterArray" :key="index" @click="mode == 'single'?filterChange(index):mulFilterChange(index)">
						{{item}}
						<uni-icons v-if="index == multipleIndexes[index] && !$scopedSlots.icon" type="checkmarkempty" :color="themeColor" size="20" style="float:right;"></uni-icons>
						<slot name="icon" :icon="index"></slot>
					</view>
				</view>
			</scroll-view>
			<view class="filterButton" v-if="mode != 'single'">
				<button type="default" class="button giveup" @click="close">取消</button>
				<button type="primary" class="button" :style="{'backgroundColor':backgroundColor}" @click="confirm">确定</button>
			</view>
		</view>
	</uni-drawer>
</template>

<script>
	import {uniDrawer} from '@dcloudio/uni-ui'
	export default {
		props:{
			filterArray: {
				type: Array,
				default: () => []
			},
			mode: {
				type: String,
				default: 'single'
			},
			backgroundColor: {
				type: String,
				default: '#fff'
			},
			width: {
				type: String,
				default: '300px'
			},
			popPosition:{
				type: String,
				default: 'right'
			},
			title:{
				type: String,
				default: ''
			},
			currentName:{
				type: String||Number,
				default: ''
			}
		},
		data() {
			return {
				multiple: [],
				multipleIndexes: []
			}
		},
		watch:{
			currentName:{
				handler: function(val,old){
					this.multipleIndexes = [];
					let index = this.filterArray?.findIndex((item,index) => item == val);
					this.$set(this.multipleIndexes, index, index)
				},
				immediate:true
			}
		},
		methods: {
			// 打开弹窗
			open(){
				this.$refs.draw.open();
			},
			changeDrawer(data){
				if(!data) if(this.mode === 'multiple') this.confirm();
			},
			// 关闭弹窗
			close(){
				this.$refs.draw.close();
			},
			filterChange: _.debounce(function(index) {
				if(this.currentName == this.filterArray[index]) return
                this.multipleIndexes = [];
                this.$set(this.multipleIndexes, index, index)
                this.$emit('filterChange',index);
            }, 200),
			// 多选,将选中项的index存于multiple
			mulFilterChange(index){
				this.multipleIndexes[index] == null ? this.$set(this.multipleIndexes, index, index) : this.$set(this.multipleIndexes, index, null)
			},
			// 确定,点击后返回index数组
			confirm(){
				this.$emit('filterChange', this.multipleIndexes);
				this.$refs.draw.close();
			}
		}
	}
</script>

<style lang="scss">
.filterUl{
	width: 100%;
	height: 100%;
	background-color: color(bg);
	.popHeader {
		height: 100rpx;
		line-height: 100rpx;
		padding: 0 16rpx;
		border-bottom: 2rpx solid color(bd);
		.title {
			font-size: 40rpx;
			font-weight: 700;
			color: color(th);
			margin-left: 32rpx;
		}
		::v-deep .uni-icons{
			vertical-align: sub;
		}
	}
	.filterBox{
		width: 100%;
		height: calc(100% - 91px);
		overflow: auto;
		display: flex;
		flex-direction: column;
		.filterItem{
			flex: 1;
			width: 100%;
			.filterList{
				height: 92rpx;
				text-align: start;
				padding: 0 16px;
				line-height: 92rpx;
				box-sizing: border-box;
				border-bottom: 2rpx solid color(bg);
				background-color: #fff;
				@include radius(mini);
				color: color(tb);
				margin: 8px 16px;
			}
		}
	}
	.filterButton{
		width: 100%;
		height: 80rpx;
		line-height: 80rpx;
		.button{
			height: 56rpx;
			@include font(28);
			@include radius(large);
			padding: 0;
			line-height: 56rpx;
			margin-left: 16px;
			float: right;
			width: 30%;
			margin-top: 12rpx;
			&::after{
				border: 0;
			}
		}
		.giveup{
			background-color: transparent;
			color: color(tb);
			border: 1px solid #e0e0e0;
			margin-right: 16px;
		}
	}
}
</style>

组件还是得慢慢改,还是没有封装的特别完美,有需要的大家就copy走,自己再改改~
具体样式如下:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值