使用Composition API时如何在Vuex store中正确实现router路由跳转
问题原因分析
你遇到的问题是三个错误共同导致的:
- 直接从
vue-router包导入的内容不是你项目里的路由实例,无法直接调用push方法 - 你定义的action函数名和导入的router变量重名,函数作用域内会覆盖外部导入的变量,导致访问到undefined
- 你当前的
router/index.js只导出了路由配置数组,没有导出创建好的路由实例,所以直接导入也没法调用跳转方法
解决步骤
第一步:修改router/index.js,导出路由实例
你现在的router/index.js只配置了路由规则,需要补充创建路由实例的逻辑,修改后代码如下:
import { createRouter, createWebHistory } from 'vue-router' const routes = [ // 你原来的所有路由配置保持不变 { path: '/', component: () => import('layouts/client.vue'), children: [ { path: '', component: () => import('pages/client/Index.vue') } ] }, { path: '/admin', component: () => import('layouts/admin.vue'), children: [ { path: '', component: () => import('pages/admin/Index.vue') } ] }, { path: '/admin/products', component: () => import('layouts/admin.vue'), children: [ { path: '', component: () => import('pages/admin/Products.vue') } ] }, { path: '/admin/vendas', component: () => import('layouts/admin.vue'), children: [ { path: '', component: () => import('pages/admin/CheckoutPurchases.vue') } ] }, { path: '/admin/products/createProduct', component: () => import('layouts/admin.vue'), children: [ { path: '', component: () => import('pages/admin/CreateProduct.vue') } ] }, { path: '/checkout', component: () => import('layouts/checkout.vue'), children: [ { path: '', component: () => import('pages/checkout/Index.vue') } ] }, { path: '/membro/:id', // beforeEnter: (to, from, next) => AuthGuard(to, from, next, store), component: () => import('layouts/basic.vue'), children: [ { path: '', component: () => import('pages/checkout/CheckoutMember.vue') } ] }, { path: '/adminlogin', // beforeEnter: (to, from, next) => AuthGuard(to, from, next, store), component: () => import('layouts/basic.vue'), children: [ { path: '', component: () => import('pages/admin/Adminlogin.vue') } ] }, { path: '/obrigado/:id', component: () => import('layouts/checkout.vue'), children: [ { path: '', component: () => import('pages/checkout/Thanks.vue') } ] }, { path: '/checkout/:user/:product', component: () => import('layouts/checkout.vue'), children: [ { path: '', component: () => import('pages/checkout/Index.vue') } ] }, { path: '/:catchAll(.*)*', component: () => import('pages/Error404.vue') } ] // 创建路由实例 const router = createRouter({ history: createWebHistory(), // 如果需要hash模式就替换为createWebHashHistory() routes }) export default router
第二步:修改store中的代码,正确导入和使用
首先不要把action命名为router避免重名,然后导入我们刚才导出的路由实例直接调用push即可:
// 导入自己创建的路由实例,路径根据你的store文件位置调整 import router from '../../router' // 修改action名称避免和导入的router变量重名 export function jumpToProductPage ({ commit, getters, dispatch }, payload) { console.log('test:', router) router.push({ path: '/admin/products' }) }
可选方案:Pinia组合式Store中用useRouter
如果你用的是Pinia的组合式写法定义Store,也可以在定义Store的时候直接调用useRouter()获取实例:
import { defineStore } from 'pinia' import { useRouter } from 'vue-router' export const useCommonStore = defineStore('common', () => { const router = useRouter() const jumpToProductPage = () => { router.push('/admin/products') } return { jumpToProductPage } })
注:这种写法要求你调用
useCommonStore()的时候必须是在Vue组件的setup上下文,或者其他已经完成Vue实例初始化的上下文,如果是在全局非setup环境调用还是建议用第一种导入实例的写法。
内容的提问来源于stack exchange,提问作者eeerrrttt
相关产品推荐
相关产品推荐

