Saya mempunyai projek Vue3 menggunakan SSR, Vue-Cli, Vuex dan Typescript.
Dalam halaman penghalaan, saya perlu menyerahkan data ke Kedai Vuex. Dalam fail .vue, saya hanya boleh menggunakan this.$store, yang ditakrifkan jenis dalam vuex.d.ts seperti ini:
this.$store.commit("setFoo", "Bar")
Tetapi bagaimana saya boleh melakukan ini dalam fail ts (router/index.ts) tanpa contoh ini atau vue?
Saya cuba mengimport fail indeks kedai dan menyerahkannya:
import kedai daripada "@/store/index" store.commit("setFoo", "Bar")
Tetapi saya mendapat ralat:
Hartanah 'commit' tidak wujud pada jenis '() =><{ foo: string }>'.ts(2339)
simpan fail (memandangkan saya menjalankan SSR, kedai itu tidak boleh menjadi satu):
import Vuex daripada "vuex" eksport fungsi lalai () { kembalikan Vuex.Store baharu({ nyatakan: () => foo: "foo", }), mutasi: { setFoo(negeri, muatan) { state.foo = muatan }, }, }) }
Fail kedai vuex 4 dikemas kini:
import { createStore } daripada "vuex" kedai const = { nyatakan: () => foo: "foo", }) } eksport fungsi lalai () { kembalikan createStore(store) }
entry-client.js:
import createApp daripada "./main" const { app, router } = createApp() router.isReady().then(() => { app.mount("#app", benar) })
Pelayan portal.ts:
import createApp daripada "./main" eksport fungsi lalai () { const { app, router } = createApp() kembali { aplikasi, penghala, } }
main.js:
import { createSSRApp, createApp, h } daripada "vue" import { isSSR } daripada "@/helpers" import createRouter daripada "@/router" import createStore daripada "@/store" import axios daripada "axios" import VueAxios daripada "vue-axios" import Apl daripada "@/App.vue" eksport fungsi lalai () { const rootComponent = { render: () => komponen: {App}, } const app = (isSSR() ? createSSRApp : createApp)(rootComponent) penghala const = createRouter() kedai const = createStore() app.use(VueAxios, axios) app.use(router) app.use(store) app.provide("axios", app.config.globalProperties.axios) kembali { aplikasi, penghala, kedai, } }
router/index.ts:
import { createRouter, createWebHistory, createMemoryHistory } daripada "vue-router" import kedai daripada "@/store/index" import axios daripada "axios" import MockAdapter daripada "axios-mock-adapter" import { route } daripada "./routes" import { isSSR } daripada "@/helpers" sejarah const = isSSR() ?createMemoryHistory() : createWebHistory(process.env.BASE_URL) const router = createRouter({laluan, sejarah}) router.beforeEach(async (ke, dari, seterusnya) => { // buat barang dengan kedai }) eksport fungsi lalai () { penghala kembali }包.json:
"scripts": { "build:all": "npm run build:client && npm run build:server", "build:client": "vue-cli-service build --dest dist/client", "build:server": "eksport SSR=1 || set SSR=1&& vue-cli-service build --dest dist/server", "build:server:dev": "eksport SSR=1 || set SSR=1&& vue-cli-service build --mod development --dest dist/server", "serve:client": "vue-cli-service serve", "serve:server": "node ./dist/server/server.js", "lint": "vue-cli-service lint" }, "kebergantungan": { "@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", "lebih cantik": "^2.2.1", "sass-loader": "^8.0.2", "typescript": "~4.1.5", "webpack-manifest-plugin": "^4.0.2", "webpack-node-externals": "^3.0.0" }
Eksport lalai anda ialah fungsi
export default function () {
Saya rasa apa yang anda mahu lakukan ialah ini:
export default new Vuex.Store({...})
Jika anda ingin mengekalkannya sebagai fungsi, anda juga boleh mencuba
store().commit
tetapi kemudian setiap panggilan ke kedai() akan mencipta contoh Vuex baharuSila ambil perhatian bahawaElakkan singleton yang berstatus negaraPeraturan ini terpakai bukan sahaja pada contoh apl utama dan storan, tetapi juga padapenghala
Semasa anda
Router/index.ts
mencipta singleton yang berstatus tinggi. Anda perlu mencipta fungsi "kilang penghala" supaya setiap permintaan pelayan mendapat contoh penghala baharu. Manfaat lain ialah kini anda boleh menghantar contoh storan kepadanyaRouter/index.ts
Sila ambil perhatianbahawa kedua-dua berkas pelayan dan klien harus menggunakan
createSSRApp
- jika menggunakancreateApp
standard,createSSRApp
- 如果使用标准的createApp
penghidratan pelanggantidak akan berfungsi dengan baikmain.js