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" />