suchen

Heim  >  Fragen und Antworten  >  Hauptteil

Wie integriere ich den Vuex Store in den Router in der Vue 3 SSR-Anwendung?

<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粉883223328P粉883223328462 Tage vor544

Antworte allen(2)Ich werde antworten

  • P粉693126115

    P粉6931261152023-08-26 09:40:03

    您的默认导出是一个函数

    export default function () {

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

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

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

    Antwort
    0
  • P粉811349112

    P粉8113491122023-08-26 09:19:19

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

    您当前的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,
      }
    }
    

    Antwort
    0
  • StornierenAntwort