Vue Composition API下如何将含静态tabs的Nav组件改为Props动态传值
改造方案
1. 修改ProgramModal子组件
第一步:定义Tab项类型并声明Props
你提到的泛型定义在Vue2组合式API中可以通过Array as () => 自定义类型[]的方式实现,我们同时将选中状态放到子组件内部维护,避免直接修改props违反单向数据流规则:
<template> <div> <div class="sm:hidden"> <label for="tabs" class="sr-only">Select a tab</label> <select id="tabs" name="tabs" class="block w-full focus:ring-indigo-500 focus:border-indigo-500 border-gray-300 rounded-md" > <option v-for="tab in tabs" :key="tab.name" :selected="tab.id === currentActiveId"> {{ tab.name }} </option> </select> </div> <div class="hidden sm:block"> <nav class="flex items-center space-x-4"> <a v-for="tab in tabs" :key="tab.name" :href="tab.href" :class="[ tab.id === currentActiveId ? 'bg-purple-70 q0 text-white' : 'text-purple-700 hover:text-gray-700', 'px-12 py-2 rounded-full font-bold text-xl', ]" @click="changeTab(tab)" > {{ tab.name }} </a> </nav> </div> <div class="hidden sm:block"> <div v-for="tab in tabs" :key="tab.name" :href="tab.href" class="px-12 flex justify-center" :class="[tab.id === currentActiveId || 'hidden']" @click="changeTab(tab)" > {{ tab.id }} - {{ tab.name }} - {{ tab.href }} - {{ tab.title }} </div> </div> </div> </template> <script lang="ts"> import { defineComponent, ref, computed } from '@vue/composition-api' import i18n from '@/setup/i18n' // 定义Tab项的泛型接口 export interface TabItem { id: number title: string imageSrc: string content: string name: string href: string } export default defineComponent({ name: 'ProgramModal', // 声明接收的props props: { tabs: { // 泛型定义数组类型 type: Array as () => TabItem[], required: false, // 保留原来的静态数据作为默认值,不传props也能正常运行 default: () => [ { id: 1, title: 'test title one', imageSrc: '/programs/test1.png', content: '', name: 'LOREM', href: '#test1', }, { id: 2, title: 'test title two', imageSrc: '/programs/test2.png', content: '', name: 'IPSUM', href: '#test2', }, { id: 3, title: 'test title three', imageSrc: '/programs/test3.png', content: '', name: 'PDF', href: '#test3', }, ] }, // 可选:支持父组件指定默认选中的tab id defaultActiveId: { type: Number, default: 1 } }, setup(props) { const ariaLabel = computed(() => i18n.t('share') as string) // 内部维护选中状态,不直接修改父组件传入的props const currentActiveId = ref(props.defaultActiveId) const changeTab = (selectedTab: TabItem) => { currentActiveId.value = selectedTab.id } return { currentActiveId, changeTab, ariaLabel, } }, }) </script>
2. 修改父组件传入自定义tabs
父组件中定义自己需要的tabs数组,通过props传给子组件即可:
<template> <!-- 传入自定义tabs,也可以指定defaultActiveId修改默认选中项 --> <ProgramModal :tabs="customTabs" :default-active-id="2" /> </template> <script lang="ts"> import ProgramModal, { TabItem } from '@/components/ProgramModal.vue' import { defineComponent, ref } from '@vue/composition-api' export default defineComponent({ name: 'Home', components: { ProgramModal, }, setup() { const isModalOpen = ref(true) const showModal = () => { isModalOpen.value = true } // 自定义要传入的tabs数据,可根据业务需求动态修改 const customTabs = ref<TabItem[]>([ { id: 1, title: '首页', imageSrc: '/programs/home.png', content: '首页内容', name: '首页', href: '#home', }, { id: 2, title: '数据列表', imageSrc: '/programs/list.png', content: '列表内容', name: '列表', href: '#list', }, { id: 3, title: '个人中心', imageSrc: '/programs/mine.png', content: '我的内容', name: '我的', href: '#mine', }, ]) return { isModalOpen, showModal, customTabs } }, }) </script>
扩展说明:如果需要父组件控制选中状态
如果你的业务需要父组件完全管控tab的选中状态,可以将子组件内部的currentActiveId改为通过emit通知父组件修改,父组件再通过prop把选中值传回来,也就是标准的v-model双向绑定模式。
内容的提问来源于stack exchange,提问作者Jesus
相关产品推荐
相关产品推荐

