Wie integriere ich den Vuex Store in den Router in der Vue 3 SSR-Anwendung?
P粉883223328
P粉883223328 2023-08-25 10:09:45
0
2
559
<p>Ich habe ein Vue3-Projekt mit SSR, Vue-Cli, Vuex und Typescript. </p> <p>Auf der Routing-Seite muss ich Daten an den Vuex Store übermitteln. In der .vue-Datei kann ich einfach this.$store verwenden, das in vuex.d.ts wie folgt typdefiniert ist: </p> <pre class="brush:php;toolbar:false;">this.$store.commit("setFoo", "Bar")</pre> <p>Aber wie kann ich das in einer TS-Datei (router/index.ts) ohne diese oder eine Vue-Instanz tun? </p> <p>Ich habe versucht, die Filialindexdatei zu importieren und einzureichen: </p> <pre class="brush:php;toolbar:false;">Store importieren aus „@/store/index“ store.commit("setFoo", "Bar")</pre> <p>Aber ich habe eine Fehlermeldung erhalten: </p> <blockquote> <p>Eigenschaft 'commit' existiert nicht für Typ '() => Store<{ foo: string }>'ts(2339)</p> </blockquote> <p>Store-Datei (da ich SSR verwende, kann der Store kein Singleton sein): </p> <pre class="brush:php;toolbar:false;">Vuex aus „vuex“ importieren Standardfunktion exportieren () { neues Vuex.Store({ zurückgeben Zustand: () => ({ foo: „foo“, }), Mutationen: { setFoo(state, payload) { state.foo = Nutzlast }, }, }) }</pre> <p>Aktualisierte Vuex 4-Store-Datei: </p> <pre class="brush:php;toolbar:false;">import { createStore } from „vuex“ const store = { Zustand: () => ({ foo: „foo“, }) } Standardfunktion exportieren () { return createStore(store) }</pre> <p>entry-client.js:</p> <pre class="brush:php;toolbar:false;">createApp aus „./main“ importieren const { app, router } = createApp() router.isReady().then(() => { app.mount("#app", true) })</pre> <p>Portal server.ts:</p> <pre class="brush:php;toolbar:false;">createApp aus „./main“ importieren Standardfunktion exportieren () { const { app, router } = createApp() zurückkehren { App, Router, } }</pre> <p>main.js:</p> <pre class="brush:php;toolbar:false;">import { createSSRApp, createApp, h } from „vue“ importiere { isSSR } aus „@/helpers“ createRouter aus „@/router“ importieren createStore aus „@/store“ importieren Axios aus „axios“ importieren VueAxios aus „vue-axios“ importieren App aus „@/App.vue“ importieren Standardfunktion exportieren () { const rootComponent = { render: () => Komponenten: {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) zurückkehren { App, Router, speichern, } }</pre> <p>router/index.ts:</p> <pre class="brush:php;toolbar:false;">import { createRouter, createWebHistory, createMemoryHistory } from „vue-router“ Shop importieren aus „@/store/index“ Axios aus „axios“ importieren MockAdapter aus „axios-mock-adapter“ importieren {Routen} aus „./routes“ importieren importiere { isSSR } aus „@/helpers“ const History = isSSR() ?createMemoryHistory() : createWebHistory(process.env.BASE_URL) const router = createRouter({ Routen, Verlauf }) router.beforeEach(async (to, from, next) => { // Sachen mit Store machen }) Standardfunktion exportieren () { Rückrouter }</pre> <p>包.json:</p> <pre class="brush:php;toolbar:false;">"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 dienen“, „serve:server“: „node ./dist/server/server.js“, „lint“: „vue-cli-service lint“ }, "Abhängigkeiten": { „@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“ }</pre>
P粉883223328
P粉883223328

Antworte allen(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,
  }
}
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage