vue3 v-model实例之二,tab标签页的实现
<template><div><Tab v-model="activeTab" :list="tabs" /><div><p>当前激活的 Tab 索引: {{ activeTab }}</p></div></div>
</template><script setup>
import { ref } from 'vue';
import Tab from './Tab.vue';// 模拟 tab 的列表数据
const tabs = [{ label: 'Tab 1' },{ label: 'Tab 2' },{ label: 'Tab 3' },
];// 父组件中定义一个响应式变量来控制当前激活的 Tab
const activeTab = ref(0);
</script>----------------------------------------------------------
子组件<template><div class="tab-container"><!-- Tab 标题 --><div class="tabs"><divv-for="(tab, index) in list":key="index"class="tab":class="{ active: index === activeIndex }"@click="handleTabClick(index)">{{ tab.label }}</div></div><!-- Tab 内容 --><div class="tab-content"><slot :activeIndex="activeIndex" /></div></div>
</template><script setup lang='ts'>
import { ref, reactive } from 'vue'
import { defineProps, defineEmits, watch } from 'vue';// 接收父组件传入的 props
const props = defineProps({list: {type: Array,required: true,},modelValue: {type: Number,default: 0,},
});// 定义 emit 事件,通知父组件更新激活索引
const emit = defineEmits(['update:modelValue']);// 内部的激活索引值
let activeIndex = props.modelValue;// 监听父组件传入的 modelValue,确保外部同步更新
watch(() => props.modelValue, (newVal) => {activeIndex = newVal;
});// 点击 tab 时更新激活的索引
const handleTabClick = (index) => {activeIndex = index;emit('update:modelValue', activeIndex);
};
</script><style lang='scss' scoped>
.tab-container {border: 1px solid #ccc;
}.tabs {display: flex;cursor: pointer;background-color: #f0f0f0;border-bottom: 1px solid #ccc;
}.tab {padding: 10px;flex: 1;text-align: center;
}.tab.active {background-color: #007bff;color: white;
}.tab-content {padding: 20px;
}
</style>
特别注意:以上代码let activeIndex = props.modelValue;它在web中可以正常执行。但是在基于uniapp的小程序中会出现索引值正常更新但是tab的激活样式没有更新。此时我们需要做一点改变。把activeIndex变成一个响应式对象。用ref包一下
let activeIndex = ref(props.modelValue)就可以正常执行了