uniApp实战五:自定义组件实现便捷选择

发布于:2025-07-14 ⋅ 阅读:(16) ⋅ 点赞:(0)

1.最终效果预览

QQ_1752218066233

QQ_1752218119422

QQ_1752218139510

2.快速选择组件封装

<uv-cell :border="isShowBorder">
		<template v-slot:title>
			<text class="title-key">{{ title }}</text>
		</template>

		<template v-slot:label>
			<text style="font-size: 28rpx;color: #999;">{{content}}</text>
		</template>

		<template v-slot:value>
			<view class="content">
				<view class="content-tag" v-for="(item, index) in showList" :key="index">
					<uv-tags :text="item.name" :plain="!item.checked" :name="index" shape="circle"
						@click="handleTagClick(index)">
					</uv-tags>
				</view>

			</view>
		</template>
		<template v-slot:right-icon>
			<view class="content-tag" v-if="showList.length < list.length">
				<uv-icon size="30rpx" name="arrow-right" @click="showMoreOptions"></uv-icon>
			</view>

		</template>
	</uv-cell>

基于 uv-ui 的行组件实现的快速选择,默认展示前三个值

3.弹框组件封装

<uv-popup ref="showPopup" mode="top">
		<view class="popup-content">
			<view class="popup-title">请选择</view>
			<uv-radio-group v-model="selectedIndex" @change="handleRadioChange">
				<view v-for="(item, index) in list" :key="index" style="margin-right: 10px;">
					<uv-radio :name="index">{{ item.name }}</uv-radio>
				</view>
			</uv-radio-group>
			<view class="popup-actions">
				<uv-button type="primary" @click="confirmSelection">确定</uv-button>
				<uv-button @click="closePopup">取消</uv-button>
			</view>
		</view>
	</uv-popup>

这两个放一个页面了,没必要再单独封装一个弹框组件了

4.组件逻辑实现

import {
		defineProps,
		defineEmits,
		computed,
		ref
	} from 'vue'

	const props = defineProps({
		isShowBorder: {
			type: Boolean,
			required: true
		},
		title: {
			type: String,
			required: true
		},
		content: {
			type: String,
			required: true
		},
		list: {
			type: Array,
			required: true
		},

		maxShow: {
			type: Number,
			default: 3
		}
	})
	const emit = defineEmits(['tagClick', 'tagMoreClick', 'selectionConfirmed'])
	const showList = computed(() => {
		return props.list.slice(0, props.maxShow)
	})
	const allList = computed(() => {
		return props.list
	})


	const handleTagClick = (index) => {
		emit('tagClick', index)
	}
	const handleMoreClick = () => {
		emit('tagMoreClick')
	}


	const showPopup = ref()
	const selectedIndex = ref({})
	const showMoreOptions = () => {
		showPopup.value.open()
	}
	const handleRadioChange = (index) => {
		selectedIndex.value = index
	}
	const confirmSelection = () => {
		emit('selectionConfirmed', selectedIndex.value)
		closePopup()
	}

	const closePopup = () => {
		showPopup.value.close()
	}

5.组件样式

.title-key {
		width: 150rpx;
	}

	.content {
		display: flex;
		flex-wrap: wrap;
	}

	.content-tag {
		margin: 0 0 10rpx 10rpx;
	}

	.popup-content {
		padding: 20rpx;
	}

	.popup-title {
		font-size: 32rpx;
		font-weight: bold;
		margin-bottom: 20rpx;
	}

	.popup-actions {
		display: flex;
		justify-content: space-evenly;
		margin-top: 20rpx;
	}

6.页面引入

import RowSel from '@/components/rowSel.vue'

<RowSel :isShowBorder="true" :title="'维修大类'" :content="largeContent" :list="wxLargeAllList"
				@tagClick="radio1Click" @selectionConfirmed="tagMore1Click">
</RowSel>
<RowSel :title="'维修小类'" :content="smallContent" :list="wxSmallAllList" @tagClick="radio2Click"
				@selectionConfirmed="tagMore2Click">
</RowSel>


    const radio1Click = (index) => {

	}

	const radio2Click = (index) => {

	}

	const tagMore1Click = (index) => {
		radio1Click(index)
	}
	const tagMore2Click = (index) => {
		radio2Click(index)
	}

在点击事件中实现自己的逻辑选择即可


网站公告

今日签到

点亮在社区的每一天
去签到