Vue 3 SSR 애플리케이션의 라우터에 vuex store를 통합하는 방법은 무엇입니까?
P粉883223328
2023-08-25 10:09:45
<p>SSR, Vue-Cli, Vuex 및 Typescript를 사용하는 Vue3 프로젝트가 있습니다. </p>
<p>라우팅 페이지에서 Vuex Store에 데이터를 제출해야 합니다. .vue 파일에서는 vuex.d.ts에 다음과 같이 유형이 정의된 this.$store를 간단히 사용할 수 있습니다. </p>
<pre class="brush:php;toolbar:false;">this.$store.commit("setFoo", "Bar")</pre>
<p>하지만 이 인스턴스나 vue 인스턴스 없이 ts 파일(router/index.ts)에서 이 작업을 어떻게 수행할 수 있나요? </p>
<p>매장 색인 파일을 가져와서 제출하려고 했습니다. </p>
<pre class="brush:php;toolbar:false;">"@/store/index"에서 저장소 가져오기
store.commit("setFoo", "Bar")</pre>
<p>하지만 오류가 발생했습니다: </p>
<인용문>
<p>'() => Store<{ foo: string }>' 속성에 'commit' 속성이 없습니다.ts(2339)</p>
</인용문>
<p>store 파일(SSR을 실행 중이므로 저장소는 싱글톤일 수 없습니다.): </p>
<pre class="brush:php;toolbar:false;">"vuex"에서 Vuex 가져오기
기본 함수 내보내기 () {
새로운 Vuex.Store({
상태: () =>
foo: "푸",
}),
돌연변이: {
setFoo(상태, 페이로드) {
state.foo = 페이로드
},
},
})
}</pre>
<p>업데이트된 vuex 4 저장 파일: </p>
<pre class="brush:php;toolbar:false;">"vuex"에서 { createStore } 가져오기
const 저장소 = {
상태: () =>
foo: "푸",
})
}
기본 함수 내보내기 () {
createStore(스토어) 반환
}</pre>
<p>entry-client.js:</p>
<pre class="brush:php;toolbar:false;">"./main"에서 createApp 가져오기
const { 앱, 라우터 } = createApp()
router.isReady().then(() => {
app.mount("#앱", true)
})</pre>
<p>포털 서버.ts:</p>
<pre class="brush:php;toolbar:false;">"./main"에서 createApp 가져오기
기본 함수 내보내기 () {
const { 앱, 라우터 } = createApp()
반품 {
앱,
라우터,
}
}</pre>
<p>main.js:</p>
<pre class="brush:php;toolbar:false;">"vue"에서 { createSSRApp, createApp, h } 가져오기
"@/helpers"에서 { isSSR } 가져오기
"@/router"에서 createRouter 가져오기
"@/store"에서 createStore 가져오기
"axios"에서 axios 가져오기
"vue-axios"에서 VueAxios 가져오기
"@/App.vue"에서 앱 가져오기
기본 함수 내보내기 () {
const 루트컴포넌트 = {
렌더링: () =>
구성요소: {앱},
}
const app = (isSSR() ? createSSRApp : createApp)(rootComponent)
const 라우터 = createRouter()
const 저장소 = createStore()
app.use(VueAxios, axios)
app.use(라우터)
앱.사용(스토어)
app.provide("axios", app.config.globalProperties.axios)
반품 {
앱,
라우터,
가게,
}
}</pre>
<p>라우터/index.ts:</p>
<pre class="brush:php;toolbar:false;">import { createRouter, createWebHistory, createMemoryHistory } "vue-router"에서
"@/store/index"에서 매장 가져오기
"axios"에서 axios 가져오기
"axios-mock-adapter"에서 MockAdapter 가져오기
"./routes"에서 { 경로 } 가져오기
"@/helpers"에서 { isSSR } 가져오기
const 역사 = isSSR()
? 생성메모리히스토리()
: createWebHistory(process.env.BASE_URL)
const router = createRouter({ 경로, 기록 })
router.beforeEach(async (to, from, next) => {
// store에서 작업을 수행합니다.
})
기본 함수 내보내기 () {
반납 라우터
}</pre>
<p>包.json:</p>
<pre class="brush:php;toolbar:false;">"스크립트": {
"build:all": "npm 실행 빌드:클라이언트 && npm 실행 빌드:서버",
"build:client": "vue-cli-service build --dest dist/client",
"build:server": "export SSR=1 || 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-서비스 제공",
"serve:서버": "노드 ./dist/server/server.js",
"lint": "vue-cli-service 린트"
},
"종속성": {
"@vue/server-renderer": "^3.2.4",
"축": "^0.21.1",
"core-js": "^3.6.5",
"익스프레스": "^4.17.1",
"vue": "^3.0.0",
"vue-axios": "^3.2.5",
"vue-router": "^4.0.0-0",
"vuex": "^4.0.0-0"
},
"devDependency": {
"@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",
"에슬린트": "^7.20.0",
"eslint-plugin-prettier": "^3.3.1",
"eslint-plugin-vue": "^7.6.0",
"node-sass": "^4.12.0",
"더 예뻐요": "^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
을 사용하는 경우createSSRApp
- 如果使用标准的createApp
클라이언트 하이드레이션이 제대로 작동하지 않습니다.main.js
으아아아