如何在Vue 3 SSR应用中,将vuex store集成到路由器中?
P粉883223328
P粉883223328 2023-08-25 10:09:45
0
2
451

我有一个使用SSR、Vue-Cli、Vuex和Typescript的Vue3项目。

在路由页面中,我需要将数据提交到Vuex Store中。在.vue文件中,我可以简单地使用this.$store,它在vuex.d.ts中进行了类型定义,如下:

this.$store.commit("setFoo", "Bar")

但是在没有this或vue实例的ts文件(router/index.ts)中,我该如何做到这一点呢?

我尝试导入store索引文件并进行提交:

import store from "@/store/index" store.commit("setFoo", "Bar")

但是我得到了一个错误:

类型“() => Store<{ foo: string; }>”上不存在属性“commit”。ts(2339)

store文件(由于我正在运行SSR,所以store不能是单例):

import Vuex from "vuex" export default function () { return new Vuex.Store({ state: () => ({ foo: "foo", }), mutations: { setFoo(state, payload) { state.foo = payload }, }, }) }

更新后的vuex 4 store文件:

import { createStore } from "vuex" const store = { state: () => ({ foo: "foo", }) } export default function () { return createStore(store) }

entry-client.js:

import createApp from "./main" const { app, router } = createApp() router.isReady().then(() => { app.mount("#app", true) })

入口服务器.ts:

import createApp from "./main" export default function () { const { app, router } = createApp() return { app, router, } }

main.js:

import { createSSRApp, createApp, h } from "vue" import { isSSR } from "@/helpers" import createRouter from "@/router" import createStore from "@/store" import axios from "axios" import VueAxios from "vue-axios" import App from "@/App.vue" export default function () { const rootComponent = { render: () => h(App), components: { App }, } const app = (isSSR() ? createSSRApp : createApp)(rootComponent) const router = createRouter() const store = createStore() app.use(VueAxios, axios) app.use(router) app.use(store) app.provide("axios", app.config.globalProperties.axios) return { app, router, store, } }

路由器/index.ts:

import { createRouter, createWebHistory, createMemoryHistory } from "vue-router" import store from "@/store/index" import axios from "axios" import MockAdapter from "axios-mock-adapter" import { routes } from "./routes" import { isSSR } from "@/helpers" const history = isSSR() ? createMemoryHistory() : createWebHistory(process.env.BASE_URL) const router = createRouter({ routes, history }) router.beforeEach(async (to, from, next) => { // do stuff with store }) export default function () { return router } 

包.json:

"脚本": { "build:all": "npm run build:client && npm run build:server", "build:client": "vue-cli-service build --dest dist/client", "build:server": "export SSR=1 || set SSR=1&& vue-cli-service build --dest dist/server", "build:server:dev": "export SSR=1 || set SSR=1&& vue-cli-service build --modedevelopment --dest dist/server", "serve:client": "vue-cli-service 服务", “服务:服务器”:“节点./dist/server/server.js”, "lint": "vue-cli-service lint" }, “依赖项”:{ "@vue/server-renderer": "^3.2.4", "axios": "^0.21.1", "core-js": "^3.6.5", "快递": "^4.17.1", "vue": "^3.0.0", "vue-axios": "^3.2.5", "vue-router": "^4.0.0-0", “vuex”:“^4.0.0-0” }, “开发依赖项”:{ "@typescript-eslint/eslint-plugin": "^4.18.0", "@typescript-eslint/parser": "^4.18.0", "@vue/cli-plugin-babel": "^5.0.0-beta.3", "@vue/cli-plugin-eslint": "^5.0.0-beta.3", "@vue/cli-plugin-router": "^5.0.0-beta.3", "@vue/cli-plugin-typescript": "^5.0.0-beta.3", "@vue/cli-plugin-vuex": "^5.0.0-beta.3", "@vue/cli-service": "^5.0.0-beta.3", "@vue/compiler-sfc": "^3.0.0", "@vue/eslint-config-prettier": "^6.0.0", "@vue/eslint-config-typescript": "^7.0.0", "axios-mock-adapter": "^1.20.0", "eslint": "^7.20.0", "eslint-plugin-prettier": "^3.3.1", "eslint-plugin-vue": "^7.6.0", “节点-sass”:“^4.12.0”, "更漂亮": "^2.2.1", "sass-loader": "^8.0.2", “打字稿”:“~4.1.5”, "webpack-manifest-plugin": "^4.0.2", “webpack-node-externals”:“^3.0.0” }
P粉883223328
P粉883223328

全部回复 (2)
P粉693126115

您的默认导出是一个函数

export default function () {

我认为您想要做的是这样的:

export default new Vuex.Store({...})

如果您想保持它作为一个函数,您也可以尝试store().commit但这样每次调用 store() 都会创建一个新的 Vuex 实例

    P粉811349112

    请注意,避免使用有状态的单例规则不仅适用于主应用实例和存储,还适用于路由器

    您当前的Router/index.ts创建了有状态的单例。您需要创建一个“路由器工厂”函数,以便每个服务器请求都获得新的路由器实例。另一个好处是现在您可以将存储实例传递给它

    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" const createHistory = isSSR() ? createMemoryHistory : createWebHistory export default function (store) { const router = createRouter({ routes, history: createHistory(process.env.BASE_URL) }) router.beforeEach(async (to, from, next) => { // do stuff with store (store comes from argument) }) return router }

    请注意服务器和客户端捆绑包都应使用createSSRApp- 如果使用标准的createApp客户端的水合作用将无法正常工作

    main.js

    import { createSSRApp, h } from "vue" import { isSSR } from "@/helpers" import createRouter from "@/router" import createStore from "@/store" import axios from "axios" import VueAxios from "vue-axios" import App from "@/App.vue" export default function () { const rootComponent = { render: () => h(App), components: { App }, } const app = createSSRApp(rootComponent) const store = createStore() const router = createRouter(store) app.use(VueAxios, axios) app.use(router) app.use(store) app.provide("axios", app.config.globalProperties.axios) return { app, router, store, } }
      最新下载
      更多>
      网站特效
      网站源码
      网站素材
      前端模板
      关于我们 免责声明 Sitemap
      PHP中文网:公益在线PHP培训,帮助PHP学习者快速成长!