Files
Friendship-and-chat-uniapp/sheep/components/segmented/segmented.vue
T
2025-11-12 10:05:42 +08:00

84 lines
1.8 KiB
Vue

<script setup>
import { computed } from 'vue';
const props = defineProps({
items: {
type: Array,
default: [],
},
modelValue: {
type: Number,
default: 0,
},
});
const emit = defineEmits(['update:modelValue', 'onChange']);
const activeStyle = computed(() => {
const x = 60 * props.modelValue;
return {
transform: `translate3d(${x}px, 0, 0)`,
};
});
const segmentedWidth = computed(() => {
return { width: `${props.items.length * 60}px` };
});
function segmentedItem(index) {
if (props.modelValue === index) return;
emit('update:modelValue', index);
emit('onChange', {
currentIndex: index,
});
}
</script>
<template>
<view class="segmentedes" :style="segmentedWidth">
<view
class="segmented-item"
v-for="(item, index) in items"
:key="item"
:class="{ active: modelValue === index }"
@click="segmentedItem(index)"
>
<text>{{ item }}</text>
</view>
<div class="active-bar" :style="activeStyle"></div>
</view>
</template>
<style scoped lang="scss">
.segmentedes {
display: flex;
position: relative;
align-items: center;
margin: 0 auto;
border: 1px solid $color-highlight-background;
border-radius: 5px;
.segmented-item {
position: relative;
z-index: 10;
flex: 1;
height: 30px;
line-height: 30px;
text-align: center;
font-size: $font-size-medium;
color: $color-text-d;
&.active {
color: $color-text;
}
}
.active-bar {
position: absolute;
left: 0;
top: 0;
width: 60px;
height: 30px;
transition: transform 0.3s;
border-radius: 5px;
background: $color-highlight-background;
}
}
</style>