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

Vue点击切换导航选中tab时报changeTab不是函数错误如何解决

Vue3 导航Tab切换功能实现方案

错误原因

你遇到的报错和功能不生效问题是以下几个语法错误导致的:

  • changeTab 函数定义在setup的return语句之后,没有暴露给模板,所以模板找不到该函数触发报错
  • 普通声明的tabs数组不是响应式数据,修改属性不会触发视图更新
  • Vue3的setup中没有this指向,你写的this.tabs访问不到数据
  • Array.find语法使用错误,需要传入匹配回调函数,不能直接传入id值
  • 导航的a标签点击会触发默认跳转行为,需要阻止默认事件

修正后完整代码

<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"
        @change="handleSelectChange"
      >
        <option 
          v-for="tab in tabs" 
          :key="tab.name" 
          :value="tab.id"
          :selected="tab.current"
        >
          {{ tab.name }}
        </option>
      </select>
    </div>
    <!-- PC端导航 -->
    <div class="hidden sm:block">
     <nav class="flex space-x-4" aria-label="Tabs" :class="bg-gray-600">
        <a 
          v-for="tab in tabs" 
          @click.prevent="changeTab(tab)"  
          :key="tab.name" 
          :href="tab.href" 
          :class="[
            tab.current ? 'bg-purple-700 text-white' : 'text-purple-700 hover:text-gray-700', 
            'px-12 py-2 font-medium text-sm rounded-full font-bold text-lg'
          ]" 
        >
          {{ tab.name }}
        </a>
      </nav>
    </div>
    <!-- 内容展示区域 -->
    <div class="tab-content mt-6 p-4 border rounded">
      <p v-for="tab in tabs" v-if="tab.current" :key="tab.id">
        这是{{ tab.name }}标签对应的内容
      </p>
    </div>
  </div>
</template>

<script>
import { ref } from 'vue'
// 初始tab数据
const initTabs = [
  { id: 1 , name: 'LOREM', href: '#test1', current: false },
  { id: 2, name: 'IPSUM', href: '#test2', current: false },
  { id: 3, name: 'PDF', href: '#test3', current: true },
]
export default {
  setup() {
    // 用ref包裹数组使其成为响应式数据
    const tabs = ref(initTabs)

    // 切换tab的函数
    function changeTab(selectedTab){
      // 先把所有tab的选中状态设为false
      tabs.value.forEach(tab => tab.current = false)
      // 把当前选中的tab设为激活
      selectedTab.current = true
    }

    // 移动端下拉切换逻辑
    function handleSelectChange(e) {
      const selectedId = Number(e.target.value)
      tabs.value.forEach(tab => {
        tab.current = tab.id === selectedId
      })
    }

    // 把需要在模板中使用的数据和函数都返回
    return {
      tabs,
      changeTab,
      handleSelectChange
    }
  },
}
</script>

<style>
  nav {
    width: max-content; 
    display: flex;
    gap: 20px; 
    background: #E5E5E5; 
    border-radius: 20px; 
}
</style>

核心改动说明

  • 引入ref对tabs数组做响应式包裹,修改属性时会自动触发视图更新
  • 调整了changeTab函数的位置,并且将函数和数据都暴露给模板
  • 修正了changeTab的逻辑,直接遍历修改选中状态
  • 给a标签添加.prevent修饰符阻止默认跳转行为
  • 新增了内容展示区域,根据current属性判断显示对应tab的内容
  • 补充了移动端下拉框的切换逻辑,实现两端适配

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 23:57:02