Files
Friendship-and-chat-uniapp/src/sheep/components/segmented/segmented.vue
T
2025-12-01 19:19:41 +08:00

58 lines
1.5 KiB
Vue

<template>
<view
class="flex items-center relative mx-auto border-1 border-solid border-#666 bg-#333 rounded-full overflow-hidden p-1"
:style="segmentedWidth"
>
<view
class="relative z-10 flex-1 h-40rpx line-height-40rpx text-center text-xs font-500 c-#fff active:text-color-theme"
v-for="(item, index) in items"
:key="index"
:class="{ active: modelValue === index }"
@click="segmentedItem(item, index)"
>
<text>{{ item.label }}</text>
</view>
<div
class="absolute h-2/3 bg-color-theme-dark rounded-full transform duration-100"
:style="activeStyle"
></div>
</view>
</template>
<script setup lang="ts">
import { computed } from 'vue';
const props = withDefaults(
defineProps<{
items?: { label: string }[];
modelValue?: number | string;
}>(),
{
items: () => [],
modelValue: 0,
},
);
const emit = defineEmits<{
(e: 'update:modelValue', index: number): void;
(e: 'change', item: { label: string }, index: number): void;
}>();
const activeStyle = computed(() => {
const x = 50 * Number(props.modelValue);
return {
width: `${50}px`,
transform: `translate3d(${x}px, 0, 0)`,
};
});
const segmentedWidth = computed(() => {
return { width: `${props.items.length * 50}px` };
});
function segmentedItem(item: { label: string }, index: number) {
if (props.modelValue === index) return;
emit('update:modelValue', index);
emit('change', item, index);
}
</script>