Vue3中useRouter在封装函数内获取为undefined的解决咨询
问题原因
Vue Router的useRouter()是Composition API钩子,它的调用必须满足两个条件:
- 处于组件的setup函数上下文内
- 或者在被组件setup/其他Composition API钩子调用的函数中执行
你的checkUserAuth是独立的普通函数,调用时不在任何组件的setup上下文里,所以useRouter()无法获取到路由实例,返回undefined。
无需传入router的解决方案
方案1:直接导入全局路由实例
在路由初始化的文件(比如@/router/index.ts)中,导出创建好的router实例:
import { createRouter, createWebHistory } from 'vue-router' import routes from './routes' // 创建路由实例并导出 export const router = createRouter({ history: createWebHistory(import.meta.env.BASE_URL), routes }) // 保留原有的app.use(router)逻辑
然后在CheckUserAuth.ts中直接导入这个全局实例,无需使用useRouter():
import { router } from '@/router' import { useUserStore } from '@/stores/user' import UserApi from '@/api/UserApi' import { TOKEN_NAME, LOGIN_PAGE_ROUTE, DASHBOARD_ROUTE } from '@/constants' export const checkUserAuth = async () => { const userStore = useUserStore() const userApi = new UserApi() const token = localStorage.getItem(TOKEN_NAME) if (!token) { await router.push({ name: LOGIN_PAGE_ROUTE }) return } const userData = await userApi.fetchMasterInfo() userStore.setUser(userData) await router.push({ name: DASHBOARD_ROUTE }) }
方案2:将函数封装为Composition API函数
如果不想依赖全局实例,可以把checkUserAuth改成需要在组件setup上下文调用的函数,这样内部就能正常使用useRouter():
import { useRouter } from 'vue-router' import { useUserStore } from '@/stores/user' import UserApi from '@/api/UserApi' import { TOKEN_NAME, LOGIN_PAGE_ROUTE, DASHBOARD_ROUTE } from '@/constants' // 定义为需要在组件setup中调用的函数 export const useCheckUserAuth = () => { const router = useRouter() const userStore = useUserStore() const userApi = new UserApi() const checkUserAuth = async () => { const token = localStorage.getItem(TOKEN_NAME) if (!token) { await router.push({ name: LOGIN_PAGE_ROUTE }) return } const userData = await userApi.fetchMasterInfo() userStore.setUser(userData) await router.push({ name: DASHBOARD_ROUTE }) } return { checkUserAuth } }
在组件中使用:
import { useCheckUserAuth } from '@/common/CheckUserAuth' import { onMounted } from 'vue' const { checkUserAuth } = useCheckUserAuth() onMounted(async () => { await checkUserAuth() })
这个方案依然保持了函数的封装性,且不需要手动传入router,只是需要在组件setup中通过useCheckUserAuth()来获取执行函数。
内容的提问来源于stack exchange,提问作者Nimble Stalker
相关产品推荐
相关产品推荐

