Files
cashier-web/src/views/marketing_center/components/tabHeader.vue

120 lines
2.5 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div class="tab_wrap">
<div class="item_wrap" :style="{ gap: `${gap}px` }">
<div class="item" :ref="el => itemRefs[index] = el" v-for="(item, index) in props.list" :key="index"
:class="{ modelValue: modelValue == index }" @click="changeHandle(index)">
<span>{{ item.label }}</span>
</div>
<div class="active_wrap" :style="{ '--left': `${leftValue}px`, '--width': `${itemsWidth[modelValue]}px` }">
</div>
</div>
</div>
</template>
<script setup>
import { ref, onMounted, nextTick, watch } from 'vue'
const props = defineProps({
// {label: '设置',value: 1}
list: {
type: Array,
default: []
}
})
const emits = defineEmits(['update:modelValue', 'change'])
const modelValue = defineModel('modelValue', {
type: [String, Number],
required: true
})
// 更新active_wrap位置
function updateActivePosition(index) {
let left = 0
itemsWidth.value.forEach((val, i) => {
if (i < index) {
left += val
}
})
leftValue.value = left + gap.value * index
}
// 改变索引
function changeHandle(index) {
modelValue.value = index
updateActivePosition(index)
emits('change', index)
}
const itemRefs = ref([])
const itemsWidth = ref([])
const gap = ref(24)
const leftValue = ref(0)
onMounted(() => {
nextTick(() => {
itemRefs.value.forEach((el, index) => {
itemsWidth.value.push(el.offsetWidth)
})
console.log('itemRefs===', itemRefs.value);
console.log('itemsWidth===', itemsWidth.value);
updateActivePosition(modelValue.value)
})
})
// 监听modelValue变化更新位置
watch(modelValue, (newVal) => {
updateActivePosition(newVal)
})
</script>
<style scoped lang="scss">
.tab_wrap {
padding: 12px;
background-color: #F8F8F8;
border-radius: 2px;
.item_wrap {
position: relative;
display: flex;
align-items: center;
.item {
padding: 0 12px;
height: 36px;
display: flex;
align-items: center;
justify-content: center;
position: relative;
z-index: 2;
cursor: pointer;
&.modelValue {
span {
color: #fff;
}
}
span {
font-size: 16px;
color: #999;
transition: all .1s ease-in-out .15s;
}
}
.active_wrap {
width: var(--width);
background-color: var(--el-color-primary);
height: 34px;
position: absolute;
top: 0;
left: var(--left);
z-index: 1;
border-radius: 2px;
transition: all .3s ease-in-out;
}
}
}
</style>