uniapp 打造自用组件库 (八) 选项切换按钮

2,214 阅读1分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

uniapp 打造自用组件库 (八) 选项切换按钮

前言

本文将带领读者使用uniapp封装一些常用组件,方便日后开发时重复使用,当然文中封装的组件不可能适配所有应用场景,但是我希望读者可以跟着我的思路实现出来,然后可以在此基础上优化改进为自己合适的,本人一个前端小菜鸡,希望大佬们可以不吝赐教,也是对我的技术水平的提升

选项切换按钮

需求

在项目开发中经常会遇到一个页面通过一组按钮来切换的情况,有些项目使用这种按钮的场景异常的频繁,所以就通过封装组件,实现了这个功能,便于我们平时的使用,并且可以自己配置各种样式,适配多个按钮溢出屏幕的情况

image.png

效果展示

应用效果

image.png

应用代码
	<view>
		<Ytitle value='选项卡按钮' pieceColor='#1E5EFF'></Ytitle>
		<view style="padding: 30rpx;">
			<!-- 由于应用场景可能存在边距,所有组件中没有默认设置边距,可以通过父元素来控制 -->
			<YtabBtns :data="list" :index.sync="index"></YtabBtns>
		</view>

		<Ytitle value='自定义颜色' pieceColor='#1E5EFF'></Ytitle>
		<view style="padding: 30rpx;background-color: #1E5EFF;">
			<!-- 由于应用场景可能存在边距,所有组件中没有默认设置边距,可以通过父元素来控制 -->
			<YtabBtns :data="list" :index.sync="index" color='#fff' background='#1E5EFF' borderColor='#fff'></YtabBtns>
		</view>

		<Ytitle value='按钮较多时' pieceColor='#1E5EFF'></Ytitle>
		<view style="padding: 30rpx;">
			<!-- 当可选择过多时可以滑动显示 -->
			<YtabBtns :data="list1" :index.sync='index1' @change='change'></YtabBtns>
		</view>
	</view>
export default {
		data() {
			return {
				index: 0,
				list: [{

					name: 'Java',
					id: 1,
				}, {

					name: 'Python',
					id: 2,
				}, {

					name: 'PHP',
					id: 3,
				}, ],

				index1: 0,
				list1: [{

					name: 'Java',
					id: 1,
				}, {

					name: 'Python',
					id: 2,
				}, {

					name: 'PHP',
					id: 3,
				}, {

					name: 'C/C++',
					id: 3,
				}, {

					name: '.NET',
					id: 3,
				}, {

					name: 'JavaScript',
					id: 3,
				}, ]
			}
		},
		methods: {
			change(info) {
				// 可以通过change事件来获取切换 也可以通过watch来监听index变化来获取切换
				uni.showToast({
					title: `你点击了${info.name}`
				})
			},
		}
	}

实现思路

利用flex布局实现使元素横向排列,通过控制文字不换行,让每个元素能够撑起盒子,然后设置边距就可以撑开按钮

完整实现代码

/**
* 切换按钮组
* index 参数必须绑定 绑定方式 :index.sync='参数'
* 若未绑定无法切换按钮
*
* change 事件 返回选中按钮所传的所有参数
*/
<template>
	<view>
		<view class="list" :style="{border:`1rpx solid ${borderColor}`}">
			<view class="item" @tap="tap_item(ind,item)" v-for="(item,ind) in data" :style="{color:index ==ind?background:color,background:ind == index?color:background,borderLeft:ind != 0?'1rpx solid '+borderColor:''}">
				{{item[listKey]}}
			</view>
		</view>
	</view>
</template>

<script>
	export default {
		props: {
			/**
			 * 展示字段的key 值为一个字符串
			 */
			listKey: {
				type: String,
				default: 'name'
			},
			/**
			 * 按钮列表 [{name:'按钮1', ...其他参数},{name:'按钮2', ...其他参数}]
			 */
			data: {
				type: Array,
				default: []
			},
			/**
			 * 前景色 文字 边框 及选中时的背景颜色
			 */
			color: {
				type: String,
				default: '#1E5EFF'
			},

			/**
			 * 背景色 未选中时背景色 及 选中时的文字颜色
			 */
			background: {
				type: String,
				default: '#FFFFFF'
			},
			/**
			 * 索引值 用来指定选中的值 绑定时需使用 .sync 
			 */
			borderColor: {
				type: String,
				default: '#1E5EFF'
			},
			/**
			 * 索引值 用来指定选中的值 绑定时需使用 .sync 
			 */
			index: {
				type: Number,
				default: 0
			},
		},
		data() {
			return {};
		},
		methods: {
			tap_item(ind, item) {
				this.$emit('change', item)
				this.$emit('update:index', ind)
			}
		}
	}
</script>

<style lang="scss" scoped>
	.list {
		display: flex;
		border-radius: 10rpx;
		max-width: 690rpx;
		flex-wrap: nowrap;
		overflow-x: scroll;

		.item {
			flex: 1;
			display: flex;
			justify-content: center;
			white-space: nowrap;
			padding: 10rpx 30rpx;
			color: #FFFFFF;
			font-size: 14px;
			transition: 0.2s;
		}
	}
</style>