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

Nuxt3触发Uncaught TypeError: n2 is not a function错误求助

Nuxt3中事件总线触发时出现Uncaught TypeError: n2 is not a function的解决思路

问题重现

使用Nuxt3开发时,点击绑定了@click.prevent="toggleSelectRow(keyword)"的按钮,控制台抛出错误:

Uncaught TypeError: n2 is not a function

相关代码如下:

发送端代码

const nuxtApp = useNuxtApp();
const toggleSelectRow = (keyword) => {
    if (keywordsSelected.value.find((kw) => kw.uid_kw === keyword.uid_kw) && props.keywords.length > 1) {
        keywordsSelected.value = []
        nuxtApp.$bus.$emit('filter-from-list', '');
    } else {
        keywordsSelected.value = [keyword]
        nuxtApp.$bus.$emit('filter-from-list', keyword.uid_kw);
  }
}

接收端代码(两种写法均报错)

匿名函数写法:

$bus.$on('filter-from-list', (newKeyword) => {   
  filters.keyword = (props.keywords.find((kw) => kw.uid_kw === newKeyword)) ? newKeyword : null   
  if (!filters.keyword) {
    refreshNuxtData('average-keyword-position');
    return;   
  }
  fetchKeywordPosition({ keyword: newKeyword }); 
});

声明式函数写法:

function filterFromList(newKeyword){
  filters.keyword = (props.keywords.find((kw) => kw.uid_kw === newKeyword)) ? newKeyword : null
  if (!filters.keyword) {
    refreshNuxtData('average-keyword-position');
    return;
  }
  fetchKeywordPosition({ keyword: newKeyword });
}
$bus.$on('filter-from-list', filterFromList);

问题特点:刷新页面后功能恢复正常,再次操作可能复现错误。

可能的原因及解决方案

1. 事件总线绑定/解绑的生命周期问题

Nuxt3中如果事件总线未在组件正确的生命周期内绑定和解绑,容易出现回调函数上下文丢失的情况。

  • 解决办法:在组件onMounted钩子中绑定事件,onUnmounted钩子中解绑事件,避免内存泄漏和上下文异常:
import { onMounted, onUnmounted } from 'vue';

onMounted(() => {
  $bus.$on('filter-from-list', filterFromList);
});

onUnmounted(() => {
  $bus.$off('filter-from-list', filterFromList);
});

2. 回调内函数的上下文丢失

错误中的n2是压缩后的函数名,大概率指向refreshNuxtData或fetchKeywordPosition,这两个函数调用时可能失去了正确的上下文。

  • 检查与解决:
    • 确认refreshNuxtData是通过useNuxtData正确获取的,fetchKeywordPosition的定义和导入无异常;
    • 如果fetchKeywordPosition是类方法,调用时绑定上下文:
      fetchKeywordPosition.bind(this)({ keyword: newKeyword });
      
    • 或者将fetchKeywordPosition定义为箭头函数,确保上下文不丢失:
      const fetchKeywordPosition = async ({ keyword }) => {
        // 业务逻辑
      };
      

3. 事件总线的替代方案

事件总线本身容易引发上下文和生命周期问题,建议改用Nuxt3官方推荐的跨组件通信方式:

  • Pinia状态管理示例:
    // 定义store
    import { defineStore } from 'pinia';
    export const useKeywordStore = defineStore('keyword', {
      state: () => ({ selectedKeyword: null }),
      actions: {
        setSelectedKeyword(uid) {
          this.selectedKeyword = uid;
        }
      }
    });
    
    // 发送端组件
    const keywordStore = useKeywordStore();
    const toggleSelectRow = (keyword) => {
      // 原逻辑处理
      keywordStore.setSelectedKeyword(keyword.uid_kw || null);
    };
    
    // 接收端组件
    const keywordStore = useKeywordStore();
    watch(() => keywordStore.selectedKeyword, (newKeyword) => {
      // 原filterFromList的逻辑
    });
    

4. 响应式数据更新时机冲突

filters.keyword的更新可能和后续函数调用时机冲突,刷新后状态重置暂时恢复正常。

  • 解决办法:用nextTick延迟执行后续逻辑,确保响应式数据更新完成:
function filterFromList(newKeyword){
  filters.keyword = (props.keywords.find((kw) => kw.uid_kw === newKeyword)) ? newKeyword : null
  if (!filters.keyword) {
    nextTick(() => refreshNuxtData('average-keyword-position'));
    return;
  }
  nextTick(() => fetchKeywordPosition({ keyword: newKeyword }));
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 12:35:01