Bagaimana untuk mengintegrasikan kedai vuex ke penghala dalam aplikasi Vue 3 SSR?
P粉883223328
P粉883223328 2023-08-25 10:09:45
0
2
570
<p>Saya mempunyai projek Vue3 menggunakan SSR, Vue-Cli, Vuex dan Typescript. </p> <p>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: </p> <pre class="brush:php;toolbar:false;">this.$store.commit("setFoo", "Bar")</pre> <p>Tetapi bagaimana saya boleh melakukan ini dalam fail ts (router/index.ts) tanpa contoh ini atau vue? </p> <p>Saya cuba mengimport fail indeks kedai dan menyerahkannya: </p> <pre class="brush:php;toolbar:false;">import kedai daripada "@/store/index" store.commit("setFoo", "Bar")</pre> <p>Tetapi saya mendapat ralat: </p> <blockquote> <p>Hartanah 'commit' tidak wujud pada jenis '() =><{ foo: string }>'.ts(2339)</p> </blockquote> <p>simpan fail (memandangkan saya menjalankan SSR, kedai itu tidak boleh menjadi satu): </p> <pre class="brush:php;toolbar:false;">import Vuex daripada "vuex" eksport fungsi lalai () { kembalikan Vuex.Store baharu({ nyatakan: () => foo: "foo", }), mutasi: { setFoo(negeri, muatan) { state.foo = muatan }, }, }) }</pre> <p>Fail kedai vuex 4 dikemas kini: </p> <pre class="brush:php;toolbar:false;">import { createStore } daripada "vuex" kedai const = { nyatakan: () => foo: "foo", }) } eksport fungsi lalai () { kembalikan createStore(store) }</pre> <p>entry-client.js:</p> <pre class="brush:php;toolbar:false;">import createApp daripada "./main" const { app, router } = createApp() router.isReady().then(() => { app.mount("#app", benar) })</pre> <p>Pelayan portal.ts:</p> <pre class="brush:php;toolbar:false;">import createApp daripada "./main" eksport fungsi lalai () { const { app, router } = createApp() kembali { aplikasi, penghala, } }</pre> <p>main.js:</p> <pre class="brush:php;toolbar:false;">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, } }</pre> <p>router/index.ts:</p> <pre class="brush:php;toolbar:false;">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 }</pra> <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": "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" }</pre>
P粉883223328
P粉883223328

membalas semua(2)
P粉693126115

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 baharu

P粉811349112

Sila ambil perhatian bahawa Elakkan singleton yang berstatus negaraPeraturan ini terpakai bukan sahaja pada contoh apl utama dan storan, tetapi juga pada penghala

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 kepadanya

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
  }

Sila ambil perhatian bahawa kedua-dua berkas pelayan dan klien harus menggunakan createSSRApp - jika menggunakan createApp standard, createSSRApp - 如果使用标准的createApppenghidratan pelanggan tidak akan berfungsi dengan baik

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,
  }
}
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan