Vue3 SSR项目中如何在router路由文件内调用Vuex Store提交数据
你当前@/store/index.ts导出的是生成Store实例的工厂函数,不是Store实例本身,直接调用store.commit相当于调用函数上的commit属性,自然不存在。而且SSR场景要求每个请求生成独立的store、router、app实例,不能用全局单例,所以也不能直接在store文件里实例化导出。
具体改造方案如下:
第一步 改造路由工厂函数,接收Store实例作为入参
把路由实例创建、守卫逻辑都移入导出的工厂函数内,接收当前请求对应的Store实例,这样守卫里就能直接调用store的API:
// router/index.ts import { createRouter, createWebHistory, createMemoryHistory } from "vue-router" import axios from "axios" import MockAdapter from "axios-mock-adapter" import { routes } from "./routes" import { isSSR } from "@/helpers" // 引入你Store的类型声明,和vuex.d.ts里的定义对齐即可 import type { Store } from "vuex" interface State { foo: string } export default function (store: Store<State>) { const history = isSSR() ? createMemoryHistory() : createWebHistory(process.env.BASE_URL) const router = createRouter({ routes, history }) router.beforeEach(async (to, from, next) => { // 直接用传入的store操作,类型也正常 store.commit("setFoo", "Bar") next() }) return router }
第二步 调整main.js的初始化逻辑,传入Store实例
在main.js中先实例化store,再传入createRouter生成路由实例,保证同一次请求的router和store是绑定的:
// main.js 对应部分修改 const store = createStore() // 把实例化好的store传给路由工厂 const router = createRouter(store) app.use(VueAxios, axios) app.use(router) app.use(store)
这样改造后既符合SSR每个请求独立实例的要求,也能在路由守卫中正常调用Store的commit/dispatch等API,TS类型也能正常匹配不会报错。
内容的提问来源于stack exchange,提问作者Per
相关产品推荐
相关产品推荐

