Wie integriere ich den Vuex Store in den Router in der Vue 3 SSR-Anwendung?
P粉883223328
2023-08-25 10:09:45
<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>
您的默认导出是一个函数
export default function () {
我认为您想要做的是这样的:
export default new Vuex.Store({...})
如果您想保持它作为一个函数,您也可以尝试
store().commit
但这样每次调用 store() 都会创建一个新的 Vuex 实例请注意,避免使用有状态的单例规则不仅适用于主应用实例和存储,还适用于路由器
您当前的
Router/index.ts
创建了有状态的单例。您需要创建一个“路由器工厂”函数,以便每个服务器请求都获得新的路由器实例。另一个好处是现在您可以将存储实例传递给它Router/index.ts
请注意,服务器和客户端捆绑包都应使用
createSSRApp
- 如果使用标准的createApp
,客户端的水合作用将无法正常工作main.js