Vue 3 SSR 앱에서 라우터의 vuex 스토어를 사용하려면 어떻게 해야 합니까?
SSR, Vue-Cli, Vuex 및 Typescript를 사용하는 Vue3 프로젝트가 있습니다.
라우터 페이지에서 데이터를 Vuex Store에 커밋해야 합니다..vue 파일에서는 이것을 사용합니다.vuex.d.ts로 입력되는 $store는 다음과 같습니다.
this.$store.commit("setFoo", "Bar")
그러나 이 인스턴스 또는 vue 인스턴스가 없는 ts 파일(라우터/index.ts)에서 이를 수행하려면 어떻게 해야 합니까?
저장소 인덱스 파일을 가져오고 다음을 커밋했습니다.
import store from "@/store/index"
store.commit("setFoo", "Bar")
그런데 에러가 난다.
'() = > 저장 유형 <{ foo: string; } >'ts(2339)에 'commit' 속성이 없습니다.
저장소 파일(SSR를 실행 중이므로 저장소는 싱글톤일 수 없습니다):
import Vuex from "vuex"
export default function () {
return new Vuex.Store({
state: () => ({
foo: "foo",
}),
mutations: {
setFoo(state, payload) {
state.foo = payload
},
},
})
}
vuex 4에 대한 저장소 파일 업데이트:
import { createStore } from "vuex"
const store = {
state: () => ({
foo: "foo",
})
}
export default function () {
return createStore(store)
}
entry-client.syslog:
import createApp from "./main"
const { app, router } = createApp()
router.isReady().then(() => {
app.mount("#app", true)
})
entry-server.ts:
import createApp from "./main"
export default function () {
const { app, router } = createApp()
return {
app,
router,
}
}
main.filename:
import { createSSRApp, createApp, 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 = (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)
return {
app,
router,
store,
}
}
Router/index.ts:
import { createRouter, createWebHistory, createMemoryHistory } from "vue-router"
import store from "@/store/index"
import axios from "axios"
import MockAdapter from "axios-mock-adapter"
import { routes } from "./routes"
import { isSSR } from "@/helpers"
const history = isSSR()
? createMemoryHistory()
: createWebHistory(process.env.BASE_URL)
const router = createRouter({ routes, history })
router.beforeEach(async (to, from, next) => {
// do stuff with store
})
export default function () {
return router
}
패키지json:
"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 serve",
"serve:server": "node ./dist/server/server.js",
"lint": "vue-cli-service lint"
},
"dependencies": {
"@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"
}
스테이트풀 싱글톤 회피 규칙은 메인앱인스턴스 및 스토어뿐만 아니라 라우터에도 적용됩니다.
현재 사용 중인 제품Router/index.ts
스테이트풀싱글톤을 만듭니다.대신 필요한 것은 각 서버 요구가 새로운 라우터 인스턴스를 얻을 수 있도록 "라우터 팩토리" 함수를 작성하는 것입니다.스토어 인스턴스를 전달할 수 있는 이점도 있습니다.
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
}
서버 번들과 클라이언트 번들은 둘 다 사용해야 합니다(표준을 사용하는 경우).createApp
, 클라이언트 측 하이드레이션이 작동하지 않습니다.
Vue는
createSSRApp
클라이언트 측 코드에서 모든 DOM 요소를 재생성하는 대신 기존 정적 HTML에 물을 공급하도록 Vue에 지시하는 방법
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,
}
}
기본 내보내기는 함수입니다.
export default function () {
대신 이걸 하고 싶었던 것 같아요.
export default new Vuex.Store({...})
기능으로서 보관하고 싶은 경우는, 시험해 볼 수도 있습니다.store().commit
그러나 store()를 호출할 때마다 새로운 Vuex 인스턴스가 생성됩니다.
언급URL : https://stackoverflow.com/questions/68993708/how-do-i-use-vuex-store-in-the-router-in-vue-3-ssr-app
'programing' 카테고리의 다른 글
const를 사용하여 변수를 초기화하려고 할 때 "initializer element is not const" 오류가 발생함 (0) | 2022.07.04 |
---|---|
Vuetify 콤보 상자 항목 템플릿이 vuex로 업데이트되지 않음 (0) | 2022.07.04 |
R_X86_64_32S 및 R_X86_64_64 재배치란 무엇입니까? (0) | 2022.07.04 |
Java: String 초기화 방법 [] (0) | 2022.07.04 |
Java에서 경로를 결합하는 방법 (0) | 2022.07.04 |