Comment intégrer le magasin Vuex dans le routeur dans l'application Vue 3 SSR ?
P粉883223328
2023-08-25 10:09:45
<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é>
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 VuexVeuillez 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 stockageRouter/index.ts
Veuillez noter que les bundles serveur et client doivent utiliser
createSSRApp
- si vous utilisez le standardcreateApp
,createSSRApp
- 如果使用标准的createApp
l'hydratation du client ne fonctionnera pas correctementmain.js