vue3实现ant-design-vue,Segmented 分段控制器 组件

1.所用的antD版本太低,没有Segmented,所以自己写个

2.效果如下图

3.难点应该在于css滑动动画

请注意vue的版本要在3.2.25版本及以上,因为用到了以下语法,如果版本低于此,那么没有滑动的动画效果

组件代码:

<script setup>
	const emit = defineEmits(['hanldeSelect'])
	const nextStyle = ref(null)
	const firstWidth = ref('66px')
	const itemRefs = ref([])
	const props = defineProps({
		selectArr: {
			type: Array,
			default: () => []
		},
	})
	const skey = ref( props.selectArr[0]?.value)

	const hanldeSelect = (value, index) => {
		skey.value = value
		const next = itemRefs?.value[index]
		nextStyle.value = calcThumbStyle(next)
		emit('hanldeSelect', value)
	}
	const calcThumbStyle = (targetElement) => {
		return {
			left: targetElement.offsetLeft,
			width: targetElement.offsetWidth
		}
	}

	onMounted(() => {
		firstWidth.value = `${itemRefs.value[0].offsetWidth}px`
	})
</script>

<template>
	<div class="select">
		<div
			class="sigment"
			:style="{
				transform: `translateX(${nextStyle?.left}px)`,
				width: nextStyle ? `${nextStyle?.width}px` : firstWidth
			}"
		></div>
		<div class="selecWrap">
			<div
				ref="itemRefs"
				v-for="(item, index) in selectArr"
				@click="hanldeSelect(item.value, index)"
				:class="[{ selectActive: item.value === skey }, 'selecItem']"
				:key="item.value"
			>
				{{ item.label }}
			</div>
		</div>
	</div>
</template>

<style lang="less" scoped>
	.select {
		position: relative;
		background-color: #f1f2f6;
		padding: 0px 2px;
		.sigment {
			position: absolute;
			z-index: 2;
			background-color: #ffffff;
			// box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.03), 0 1px 6px -1px rgba(0, 0, 0, 0.02), 0 2px 4px 0 rgba(0, 0, 0, 0.02);
			width: 66px;
			height: 28px;
			top: 2px;
			border-radius: 4px;
			transition: transform 0.3s cubic-bezier(0.645, 0.045, 0.355, 1), width 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
			will-change: transform, width;
		}
		.selecWrap {
			z-index: 3;
			position: relative;
			display: flex;
			align-items: center;
			font-family: PingFang SC;
			font-size: 16px;
			font-weight: 400;
			color: #888;
			height: 32px;
			border-radius: 4px;
			.selecItem {
				cursor: pointer;
				padding: 2px 12px;
			}
			.selectActive {
				color: #00a955;
			}
		}
	}
</style>

使用:

	const selectArr= [
		{ label: '年度', value: 'Y' },
		{ label: '月度', value: 'M' }
	]		
	const hanldeSelect = (value) => {
	}



<Segmented @hanldeSelect="hanldeSelect" :selectArr="selectArr" />

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值