You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue.js可复用Tabs组件如何实现可自定义头部标题?

优化TabsWrapper组件的自定义头部标题实现

我通过教程实现了可复用Tabs组件,现在需要给TabsWrapper组件添加可自定义的主头部标题,让切换标签页时主头部能显示对应Tab的自定义标题。目前尝试提取Tab的headtitle属性来实现,但希望有更优方案。相关代码如下:

页面引入组件代码

<TabsWrapper>
  <Tab title="Tab 1" headtitle="主标题1">Hello 1</Tab>
  <Tab title="Tab 2" headtitle="主标题2">Hello 2</Tab>
  <Tab title="Tab 3">Hello 3</Tab> <!-- 未设置headtitle时可复用title -->
  <Tab title="Tab 4" headtitle="主标题4">Hello 4</Tab>
</TabsWrapper>

TabsWrapper原有代码

<template>
  <div class="tabs">
    <div class="tab_header"></div>
    <ul class="tabs_header">
      <li 
        v-for="title in tabTitles" 
        :key="title"
        @click="selectedTitle = title"
        :class="{ selected: title === selectedTitle }"
      >
        {{ title }}
      </li>
    </ul>
    <slot />
  </div>
</template>
<script>
import { ref, provide } from 'vue';
export default {
  setup(props, { slots }) {
    const tabTitles = ref(slots.default().map(tab => tab.props.title))
    const selectedTitle = ref(tabTitles.value[0])
    provide("selectedTitle", selectedTitle)
    return {
      selectedTitle,
      tabTitles,
    }
  }
}
</script>

我尝试的实现代码

<template>
 <div class="tabs">
    <div class="tab_header" v-for="headtitle in headTitles" :key="headtitle">{{headtitle}}</div>
    <ul class="tabs_header">
      <li 
        v-for="title in tabTitles" 
        :key="title"
        @click="selectedTitle = title"
        :class="{ selected: title === selectedTitle }"
      >
        {{ title }}
      </li>
    </ul>
    <slot />
  </div>
</template>
<script>
import { ref, provide } from 'vue';
export default {
  setup(props, { slots }) {
    const tabTitles = ref(slots.default().map(tab => tab.props.title))
    const headTitles = ref(slots.default().map(tab => tab.props.headtitle))
    const selectedTitle = ref(tabTitles.value[0])
    provide("selectedTitle", selectedTitle)
    return {
      selectedTitle,
      tabTitles,
      headTitles,
    }
  }
}
</script>

优化方案

当前尝试的代码会渲染所有Tab的headtitle,不符合“切换标签页时显示对应主标题”的需求。更合理的做法是将每个Tab的title和headtitle关联存储,通过选中状态动态切换主头部标题:

<template>
  <div class="tabs">
    <!-- 动态显示当前选中Tab的主标题 -->
    <div class="tab_header">{{ currentHeadTitle }}</div>
    <ul class="tabs_header">
      <li 
        v-for="item in tabItems" 
        :key="item.title"
        @click="selectedTitle = item.title"
        :class="{ selected: item.title === selectedTitle }"
      >
        {{ item.title }}
      </li>
    </ul>
    <slot />
  </div>
</template>
<script>
import { ref, computed, provide } from 'vue';
export default {
  setup(props, { slots }) {
    // 将每个Tab的title和headtitle整合为对象数组,关联存储
    const tabItems = ref(slots.default().map(tab => ({
      title: tab.props.title,
      // 未设置headtitle时,默认使用title作为主标题
      headtitle: tab.props.headtitle || tab.props.title
    })))
    
    const selectedTitle = ref(tabItems.value[0]?.title || '')
    
    // 计算当前选中Tab对应的主标题
    const currentHeadTitle = computed(() => {
      const activeItem = tabItems.value.find(item => item.title === selectedTitle.value)
      return activeItem ? activeItem.headtitle : ''
    })
    
    provide("selectedTitle", selectedTitle)
    
    return {
      selectedTitle,
      tabItems,
      currentHeadTitle
    }
  }
}
</script>

优化点说明

  • 避免维护两个独立数组(tabTitles和headTitles),减少数据不一致的风险
  • 通过计算属性currentHeadTitle动态获取当前选中Tab的主标题,无需手动遍历
  • 增加默认值处理:当Tab未设置headtitle时,自动复用title作为主标题
  • 模板中无需循环渲染主标题,只显示当前选中项的对应内容

内容的提问来源于stack exchange,提问作者Akirambur

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 06:55:25