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
相关产品推荐
相关产品推荐

