구성 요소를 로드하기 전에 VueX 값이 로드될 때까지 기다리십시오.
사용자가 컴포넌트 URL 로드를 직접 네비게이트하려고 하면 vuex 액션으로 http 콜이 발신되어 해결되면 내 상태의 값이 정의됩니다.
http 콜이 해결되어 상태 값이 정의될 때까지 컴포넌트를 로드하지 않습니다.
예를 들어, 내 구성 요소에서
export default {
computed: {
...mapState({
// ** this value needs to load before component mounted() runs **
asyncListValues: state => state.asyncListValues
})
},
mounted () {
// ** I need asyncListValues to be defined before this runs **
this.asyncListValues.forEach((val) => {
// do stuff
});
}
}
컴포넌트를 대기시키는 방법asyncListValues
컴포넌트를 장착하기 전에 로딩할 수 있습니까?
이를 위한 한 가지 방법은 상태 값을 저장하는 것입니다.
예를 들어 스토어가 단일 API에 의존하는 경우 다음과 같은 작업을 수행합니다.단, 여러 API의 경우 각 API 로드 상태를 개별적으로 저장하거나 각 API에 대해 전용 개체를 사용하는 것이 좋습니다.
일반적으로 4가지 상태를 가질 수 있습니다.글로벌하게 액세스 가능한 모듈로 설정하는 것이 좋습니다.
// enums.js
export default {
INIT: 0,
LOADING: 1,
ERROR: 2,
LOADED: 3
};
그런 다음 변수를 vuex 상태로 저장할 수 있습니다. 여기서 apiState는 다음과 같이 초기화됩니다.INIT
어레이를 초기화할 수도 있습니다.[]
하지만 그럴 필요는 없어요
import ENUM from "@/enums";
// store.js
export default new Vuex.Store({
state: {
apiState: ENUM.INIT,
accounts: [],
// ...other state
},
mutations: {
updateAccounts (state, accounts) {
state.accounts = accounts;
state.apiState = ENUM.LOADED;
},
setApiState (state, apiState) {
state.apiState = apiState;
},
},
actions: {
loadAccounts ({commit) {
commit('setApiState', ENUM.LOADING);
someFetchInterface()
.then(data=>commit('updateAccounts', data))
.catch(err=>commit('setApiState', ENUM.ERROR))
}
}
});
그리고 나서 조금 더...computed
표시되는 컴포넌트를 전환할 수 있습니다.상태를 사용하면 Error 상태를 쉽게 식별할 수 있고 상태가 준비되지 않았을 때 로드 애니메이션을 표시할 수 있습니다.
<template>
<ChildComponent v-if="apiStateLoaded"/>
<Loader v-if="apiStateLoading"/>
<Error v-if="apiStateError"/>
</template>
<script>
import ENUM from "@/enums";
export default {
computed: {
...mapState({
apiState: state=> state.apiState
}),
apiStateLoaded() {
return this.apiState === ENUM.LOADED;
},
apiStateLoading() {
return this.apiState === ENUM.LOADING || this.apiState === ENUM.INIT;
},
apiStateError() {
return this.apiState === ENUM.ERROR;
},
})
}
</script>
차치하고...이 패턴을 사용하여 응용 프로그램을 상태 시스템으로 관리합니다.이 예에서는 vuex를 사용하지만 컴포넌트에서 사용하도록 조정할 수 있습니다.Vue.observable
(vue 2.6 이상) 또는ref
(vue3)
또는 단순히 초기화를 하는 경우asyncListValues
진열되어 있지 않은 가게에서[]
어레이를 상정하는 에러를 회피할 수 있습니다.
말씀하신 대로vue-router
질문하신 내용은beforeRouteEnter
컴포넌트의 렌더링을 지연시키기 위해 작성되었습니다.
예를 들어, "photo"라는 루트가 있는 경우:
import Photo from "../page/Photo.vue";
new VueRouter({
mode: "history",
routes: [
{ name: "home", path: "/", component: Home },
{ name: "photo", path: "/photo", component: Photo }
]
});
를 사용할 수 있습니다.beforeRouteEnter
다음과 같습니다.
<template>
<div>
Photo rendered here
</div>
</template>
<script>
export default {
beforeRouteEnter: async function(to, from, next) {
try {
await this.$store.dispatch("longRuningHttpCall");
next();
} catch(exception) {
next(exception);
}
}
}
</script>
동작은 액션이 완료될 때까지 기다렸다가 원하는 대로 상태를 갱신하고 콜을 하는 것입니다.next()
라우터에 프로세스를 속행하도록 지시합니다(컴포넌트 내의 컴포넌트).<router-view></router-view>
).
ES6가 필요 없는 예제가 필요한 경우(예를 들어 이 구문을 사용하지 않는 경우)를 알려 주십시오.
이 페이지에서 의 공식 매뉴얼을 확인할 수 있습니다.또, 다음의 방법으로 루트 레벨에 배치할 수도 있습니다.beforeEnter
.
한 가지 방법은 컴포넌트를 2개의 다른 컴포넌트로 분할하는 것입니다.데이터가 준비되면 새 상위 구성 요소가 데이터 가져오기 및 하위 구성 요소 렌더링을 처리할 수 있습니다.
부모 컴포넌트표시하다
<template>
<child-component v-if="asyncListValues && asyncListValues.length" :asyncListValues="asyncListValues"/>
<div v-else>Placeholder</div>
</template>
<script>
export default {
computed: {
...mapState({
asyncListValues: state => state.asyncListValues
})
}
}
</script>
Child Component(Child Component)표시하다
export default {
props: ["asyncListValues"],
mounted () {
this.asyncListValues.forEach((val) => {
// do stuff
});
}
}
간단한 방법:
...
watch: {
vuexvalue(newVal) {
if (newVal == 'XXXX')
this.loadData()
}
}
},
computed: {
...mapGetters(['vuexvalue'])
}
회답에 라우터를 하고 있는 는, 할 수 .RouterView
상태가 로드되었을 때.
@daniel을 @daniel로 하세요.stateLoaded
플래그를 지정합니다.여기에서는 2개의 스테이트 플래그를 사용하여 간단하게 설명하겠습니다만, 원하는 대로 상세하게 기술할 수 있습니다.
const store = createStore({
state () {
return {
mysettings: {}, // whatever state you need
stateLoaded: false,
}
},
mutations: {
set_state (state, new_settings) {
state.settings = new_settings;
state.stateLoaded = true;
},
}
}
ㅇㅇㅇㅇ에서는요.app.vue
하다
<div class="content">
<RouterView/>
</div>
변경 내용:
<div class="content">
<RouterView v-if="this.$store.state.stateLoaded"/>
</div>
v-if
하나 까딱하지 않다RouterView
stateLoaded
이 내리다true
따라서 라우터를 사용하여 렌더링하는 모든 것은 호출되지 않으므로 라우터가 로드될 때 정의되지 않은 상태 변수가 라우터에 없습니다.
물론 이 기능을 기반으로 구축하려면v-else
"로드 중... 그런 거 있잖아요 에 대비해서'이렇게 하면 안 돼요. 상태 로딩이 예상보다 오래 걸릴 경우를 대비해서요.@daniel의 multi-state 플래그를 사용하면 상태를 로드하는 데 문제가 있는지 보고하고 Retry 버튼 등을 제공할 수도 있습니다.
언급URL : https://stackoverflow.com/questions/56587777/wait-for-vuex-value-to-load-before-loading-component
'programing' 카테고리의 다른 글
null이 아닌 종료 문자열에 printf 사용 (0) | 2022.07.06 |
---|---|
null 포인터가 모든 비트0이 아닐 때 C/C++ 코드를 올바르게 쓰는 방법 (0) | 2022.07.06 |
CMAKE - 정적 라이브러리의 헤더 파일을 /usr/include에 올바르게 복사하는 방법 (0) | 2022.07.06 |
기존 JNDI HornetQ 서비스를 HA로 만들기 위한 단계? (0) | 2022.07.06 |
vuetify2를 사용하여 모든 v-card의 높이를 동일하게 하는 방법 (0) | 2022.07.06 |