a
This commit is contained in:
79
src/components/LButtonGroup.vue
Normal file
79
src/components/LButtonGroup.vue
Normal file
@@ -0,0 +1,79 @@
|
||||
<script setup>
|
||||
// 接收 type 和 options props 以及 v-model
|
||||
const props = defineProps({
|
||||
type: {
|
||||
type: String,
|
||||
default: 'purple-pink', // 默认颜色渐变
|
||||
},
|
||||
options: {
|
||||
type: Array,
|
||||
required: true, // 动态传入选项
|
||||
},
|
||||
modelValue: {
|
||||
type: String,
|
||||
default: '', // v-model 绑定的值
|
||||
},
|
||||
})
|
||||
const emit = defineEmits(['update:modelValue'])
|
||||
// 选中内容绑定 v-model
|
||||
const selected = ref(props.modelValue)
|
||||
|
||||
// 监听 v-model 的变化
|
||||
watch(() => props.modelValue, (newValue) => {
|
||||
selected.value = newValue
|
||||
})
|
||||
|
||||
// 根据type动态生成分割线的类名
|
||||
const lineClass = computed(() => {
|
||||
// 统一使用主题色渐变
|
||||
return 'bg-gradient-to-r from-red-600 via-red-500 to-red-700'
|
||||
})
|
||||
|
||||
// 计算滑动线的位置和宽度
|
||||
const slideLineStyle = computed(() => {
|
||||
const index = props.options.findIndex(option => option.value === selected.value)
|
||||
const buttonWidth = 100 / props.options.length
|
||||
return {
|
||||
width: `${buttonWidth}%`,
|
||||
transform: `translateX(${index * 100}%)`,
|
||||
}
|
||||
})
|
||||
|
||||
// 选择选项函数
|
||||
function selectOption(option) {
|
||||
selected.value = option.value
|
||||
// 触发 v-model 的更新
|
||||
emit('update:modelValue', option.value)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="relative flex">
|
||||
<div
|
||||
v-for="(option, index) in options"
|
||||
:key="index"
|
||||
class="flex-1 shrink-0 cursor-pointer py-2 text-center text-size-sm font-bold transition-transform duration-200 ease-in-out"
|
||||
:class="{ 'text-gray-900': selected === option.value, 'text-gray-500': selected !== option.value }"
|
||||
@click="selectOption(option)"
|
||||
>
|
||||
{{ option.label }}
|
||||
</div>
|
||||
<div
|
||||
class="absolute bottom-0 h-[3px] rounded transition-all duration-300"
|
||||
:style="slideLineStyle"
|
||||
:class="lineClass"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
/* 自定义样式 */
|
||||
button {
|
||||
outline: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
button:focus {
|
||||
outline: none;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user