Comment intégrer le magasin Vuex dans le routeur dans l'application Vue 3 SSR ?
P粉883223328
P粉883223328 2023-08-25 10:09:45
0
2
561
<p>J'ai un projet Vue3 utilisant SSR, Vue-Cli, Vuex et Typescript. </p> <p>Dans la page de routage, je dois soumettre des données au Vuex Store. Dans le fichier .vue, je peux simplement utiliser this.$store, qui est défini par type dans vuex.d.ts comme ceci : </p> <pre class="brush:php;toolbar:false;">this.$store.commit("setFoo", "Bar")</pre> <p>Mais comment puis-je faire cela dans un fichier ts (routeur/index.ts) sans cette instance ou vue ? </p> <p>J'ai essayé d'importer le fichier d'index du magasin et de le soumettre : </p> <pre class="brush:php;toolbar:false;">importer le magasin depuis "@/store/index" store.commit("setFoo", "Bar")</pre> <p>Mais j'ai eu une erreur : </p> <blockquote> <p>La propriété 'commit' n'existe pas sur le type '() => Store<{ foo: string }>'.ts(2339)</p> </blockquote> <p>store file (puisque j'utilise SSR, le store ne peut pas être un singleton) : </p> <pre class="brush:php;toolbar:false;">importer Vuex depuis "vuex" exporter la fonction par défaut () { renvoyer le nouveau Vuex.Store({ état : () => foo : "foo", }), mutation : { setFoo (état, charge utile) { state.foo = charge utile }, }, }) }</pré> <p>Fichier de magasin Vuex 4 mis à jour : </p> <pre class="brush:php;toolbar:false;">importer { createStore } depuis "vuex" const magasin = { état : () => foo : "foo", }) } exporter la fonction par défaut () { retourner createStore (magasin) }</pré> <p>entry-client.js :</p> <pre class="brush:php;toolbar:false;">importer createApp depuis "./main" const { application, routeur } = createApp() router.isReady().then(() => { app.mount("#app", vrai) })</pré> <p>Serveur de portail.ts :</p> <pre class="brush:php;toolbar:false;">importer createApp depuis "./main" exporter la fonction par défaut () { const { application, routeur } = createApp() retour { application, routeur, } }</pré> <p>main.js :</p> <pre class="brush:php;toolbar:false;">import { createSSRApp, createApp, h } depuis "vue" importer { isSSR } depuis "@/helpers" importer createRouter depuis "@/router" importer createStore depuis "@/store" importer des axios depuis "axios" importer VueAxios depuis "vue-axios" importer l'application depuis "@/App.vue" exporter la fonction par défaut () { const composant racine = { rendu : () => composants : {App}, } const app = (isSSR() ? createSSRApp : createApp)(rootComponent) const routeur = créerRouter() const magasin = créerStore() app.use(VueAxios, axios) app.use (routeur) app.use (magasin) app.provide("axios", app.config.globalProperties.axios) retour { application, routeur, magasin, } }</pré> <p>router/index.ts:</p> <pre class="brush:php;toolbar:false;">import { createRouter, createWebHistory, createMemoryHistory } depuis "vue-router" importer le magasin depuis "@/store/index" importer des axios depuis "axios" importer MockAdapter depuis "axios-mock-adapter" importer { routes } depuis "./routes" importer { isSSR } depuis "@/helpers" const historique = isSSR() ?createMemoryHistory() : createWebHistory(process.env.BASE_URL) const router = createRouter({ routes, historique }) router.beforeEach(async (vers, depuis, suivant) => { // faire des trucs avec le magasin }) exporter la fonction par défaut () { routeur de retour }≪/pré> <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 servir", "serve:server": "noeud ./dist/server/server.js", "lint": "vue-cli-service peluche" }, "dépendances": { "@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" }, "dépendances dev": { "@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", "plus joli": "^2.2.1", "sass-loader": "^8.0.2", "typescript": "~4.1.5", "webpack-manifest-plugin": "^4.0.2", "webpack-node-externals": "^3.0.0" }</pré>
P粉883223328
P粉883223328

répondre à tous(2)
P粉693126115

Votre export par défaut est une fonction

export default function () {

Je pense que ce que tu veux faire est ceci :

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

Si vous souhaitez le conserver en tant que fonction, vous pouvez également essayer store().commit mais chaque appel à store() créera une nouvelle instance Vuex

P粉811349112

Veuillez noter que Évitez les singletons avec étatLa règle s'applique non seulement à l'instance principale de l'application et au stockage, mais également au routeur

Votre Router/index.ts actuel crée un singleton avec état. Vous devez créer une fonction « usine de routeurs » afin que chaque requête du serveur reçoive une nouvelle instance de routeur. Un autre avantage est que vous pouvez désormais lui transmettre une instance de stockage

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
  }

Veuillez noter que les bundles serveur et client doivent utiliser createSSRApp - si vous utilisez le standard createApp, createSSRApp - 如果使用标准的createAppl'hydratation du client ne fonctionnera pas correctement

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,
  }
}
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal