You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
87 lines
1.8 KiB
87 lines
1.8 KiB
<template> |
|
<view class="tabs" ref="tab"> |
|
<view v-for="item in options" :class="modelValue === item.value ? 'tabs-item active' : 'tabs-item'" @tap="changeTab(item.value)"> |
|
<view class="tabs-item-label" :style="{width: labelFull ? '100%' : 'auto'}">{{ item.text }}</view> |
|
</view> |
|
<view class="tab-active-bar" :style="{width: `${width}px`, transform: `translateX(${left}px)`}"></view> |
|
</view> |
|
</template> |
|
<script setup> |
|
import { defineProps, defineEmits, nextTick, ref, onMounted } from 'vue' |
|
defineProps({ |
|
options: { |
|
type: Array, |
|
default: [] |
|
}, |
|
modelValue: { |
|
type: String, |
|
default: '' |
|
}, |
|
labelFull: { |
|
type: Boolean, |
|
default: false |
|
} |
|
}); |
|
const emit = defineEmits(['update:modelValue']); |
|
|
|
const tab = ref() |
|
const width = ref(0) |
|
const left = ref(0) |
|
|
|
function changeTab(value) { |
|
emit('update:modelValue', value); |
|
nextTick(() => { |
|
getActiveBarStyle() |
|
}) |
|
} |
|
|
|
onMounted(() => { |
|
nextTick(() => { |
|
getActiveBarStyle() |
|
}) |
|
}) |
|
|
|
function getActiveBarStyle() { |
|
const query = uni.createSelectorQuery().in(this); |
|
query |
|
.select(".tabs-item.active>.tabs-item-label") |
|
.boundingClientRect((data) => { |
|
width.value = data.width; |
|
left.value = data.left; |
|
}) |
|
.exec(); |
|
|
|
} |
|
</script> |
|
|
|
<style lang="scss" scoped> |
|
.tabs { |
|
display: flex; |
|
box-shadow: inset 0 -1px 0 0 #eee; |
|
position: relative; |
|
.tabs-item { |
|
width: 50%; |
|
display: flex; |
|
justify-content: center; |
|
.tabs-item-label { |
|
text-align: center; |
|
height: 84rpx; |
|
line-height: 84rpx; |
|
color: #333; |
|
} |
|
&.active { |
|
.tabs-item-label { |
|
color: var(--primary-color); |
|
} |
|
} |
|
} |
|
.tab-active-bar { |
|
height: 2px; |
|
position: absolute; |
|
bottom: 0; |
|
transition: all .3s; |
|
background-color: var(--primary-color); |
|
} |
|
} |
|
|
|
</style> |