How to integrate vuex store into router in Vue 3 SSR application?
P粉883223328
P粉883223328 2023-08-25 10:09:45
0
2
474

I have a Vue3 project using SSR, Vue-Cli, Vuex and Typescript.

In the routing page, I need to submit data to the Vuex Store. In the .vue file, I can simply use this.$store, which is type-defined in vuex.d.ts like this:

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

But how can I do this in a ts file (router/index.ts) without this or vue instance?

I tried to import the store index file and submit it:

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

But I got an error:

Property 'commit' does not exist on type '() => Store<{ foo: string; }>'.ts(2339)

store file (since I am running SSR, the store cannot be a singleton):

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

Updated vuex 4 store file:

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) })

Portal server.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, } }

router/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:

"scripts": { "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 --mode development --dest dist/server", "serve:client": "vue-cli-service serve", "serve:server": "node ./dist/server/server.js", "lint": "vue-cli-service lint" }, "dependencies": { "@vue/server-renderer": "^3.2.4", "axios": "^0.21.1", "core-js": "^3.6.5", "express": "^4.17.1", "vue": "^3.0.0", "vue-axios": "^3.2.5", "vue-router": "^4.0.0-0", "vuex": "^4.0.0-0" }, "devDependencies": { "@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", "node-sass": "^4.12.0", "prettier": "^2.2.1", "sass-loader": "^8.0.2", "typescript": "~4.1.5", "webpack-manifest-plugin": "^4.0.2", "webpack-node-externals": "^3.0.0" }
P粉883223328
P粉883223328

reply all (2)
P粉693126115

Your default export is a function

export default function () {

I think what you want to do is this:

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

If you want to keep it as a function, you can also trystore().commitbut this will create a new Vuex instance every time store() is called

    P粉811349112

    Please note thatAvoid using stateful singletonsThe rules apply not only to the main application instance and storage, but also to therouter

    Your currentRouter/index.tscreates a stateful singleton. You need to create a "router factory" function so that every server request gets a new router instance. Another benefit is that now you can pass a storage instance to it

    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 }

    Please note that,both server and client bundles should usecreateSSRApp- if using the standardcreateApp,Client Hydrationwill not work properly

    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, } }
      Latest Downloads
      More>
      Web Effects
      Website Source Code
      Website Materials
      Front End Template
      About us Disclaimer Sitemap
      php.cn:Public welfare online PHP training,Help PHP learners grow quickly!