Vuex / Vue를 사용하여 비동기 데이터 검색을 처리하는 방법
나는 공통 스택이 있는 간단한 앱을 가지고 있다.
- 백엔드 서버(레일)
- 프런트엔드 앱(Vue)
- 데이터베이스(PG)
Vue 앱은 다음과 같이 Vuex 저장소 라이브러리의 작업을 사용하여 백엔드에서 데이터를 가져온다.
// store/store.js
import Vue from 'vue';
import Vuex from 'vuex';
import * as MutationTypes from '@/store/mutation-types';
Vue.use(Vuex);
export default new Vuex.Store({
state: {
investment: {},
},
mutations: {
[MutationTypes.SET_INVESTMENT_SHOW](state, investment) {
state.investment = investment;
},
},
actions: {
fetchInvestment({ commit }, id) {
InvestmentsApi.get(id).then((response) => {
commit(MutationTypes.SET_INVESTMENT_SHOW, response.data);
});
},
},
getters: {
participation: state =>
state.investment.included[0],
},
});
이 작업은 다음과 같이 구성 요소의 생성된 라이프사이클 후크에서 호출된다.
// components/Investment.vue
import { mapActions, mapGetters } from 'vuex';
export default {
name: 'Investment',
computed: {
...mapState(['investment']),
...mapGetters(['participation']),
},
created() {
this.fetchData(this.$route.params.id);
},
methods: mapActions({
fetchData: 'fetchInvestment',
}),
};
위에 쓴 코드에 문제가 있어, 나는 실제로 다음과 같이 내 템플릿에 계산된 값 '참여'를 사용한다.
<BaseTitleGroup
:subtitle="participation.attributes.name"
title="Investissements"
/>
물론 구성 요소가 렌더링될 때 참여를 사용하기 때문에 getter 방법에서 다음과 같은 오류를 얻는다.
Error in render: "TypeError: Cannot read property '0' of undefined"
found in
---> <InvestmentSummary> at src/views/InvestmentSummary.vue
<App> at src/App.vue
<Root>
이 문제를 해결하기 위한 몇 가지 해결책이 있다고 생각하는데, 어떤 것이 가장 좋은 방법인지, 더 좋은 방법이 있는지 궁금하다.
- 첫 번째 해결 방법은 데이터를 기다리는 동안 요소가 렌더링되지 않도록 v-if 속성을 내 템플릿에 넣는 것이다.
- Con : 렌더링 오프셋(데이터가 있을 때 요소가 렌더링을 시작함)?
- Con: 비동기 데이터를 다루는 내 앱의 모든 구성 요소에 대해 해야 하는데, 직관적으로 나는 이것을 다른 곳(아마 매장)에서 처리하고 싶어.
- 요소를 렌더링하고 "로드 중..."과 같은 가짜 데이터를 저장소에 넣으십시오.."
- Con: 페이지를 로드할 때, 텍스트가 로딩에서 실제 텍스트로 전환될 때 사용자가 볼 수 있는 작은 결함은 못생겼다.
- Con: 내 가게의 빈 버전은 쓰기 힘들고 내 앱이 확장될 때 엄청나게 클 거야.
- 저장소가 아닌 초기 빈 데이터를 반환하도록 Getter 변경
- 콘: 게이터가 점점 더 복잡해 진다.
- Con: 게이터가 필요하지 않은 데이터(아마 주(州)에서 직접 액세스할 수 있을 것이다)는 것은 어떨까?
- 다른거?
위의 패턴 중 하나라도 어떤 것이 가장 좋을지 잘 모르겠다.읽어줘서 정말 고마워! 또한 나는 vue 프레임워크를 사용하지만 비동기 데이터의 현대적인 자바스크립트 프레임워크 처리와 렌더링에 대한 일반적인 질문이라고 생각해.
긴 포스트에 미안, 여기 감자 있어! (아, 9개그에는 안돼;) )
Angle에는 결국 도착하는 반응형 데이터를 처리하는 간결한 방법인 Elvis(안전한 항법) 연산자가 있다.
Vue 템플릿 컴파일러에서 사용할 수 있는 경우 템플릿은 다음과 같이 표시됨:
<BaseTitleGroup
:subtitle="participation?.attributes?.name"
title="Investissements"
/>
하지만 에반 유는 그것이 암호 냄새처럼 들린다고 말한다.
모델/상태는 가능한 한 예측 가능해야 한다.
이 의견을 컨텍스트로 확장하려고 하면 템플릿이 저장소보다 데이터 구조에 대해 더 잘 알고 있다는 것을 의미한다고 생각한다.
템플릿
"participation.attributes.name"
이는 다음을 가리키는 말이다.
state.investment.included[0].attributes.name
저장하다
state: {
investment: {},
},
Getter가 컴포넌트(및 it's template)를 서비스하기 위해 있기 때문에, 나는 Getter를 향상시키는 것을 선택할 것이다.
getters: {
participation_name: state => {
return
(state.investment.included
&& state.investment.included.length
&& state.investment[0]
&& state.investment[0].attributes
&& state.investment[0].attributes.name)
|| null;
},
<BaseTitleGroup
:subtitle="participation_name"
title="Investissements"
/>
하지만 엘비스 기능을 원한다면 믹싱으로 제공할 수 있다.
var myMixin = {
computed: {
elvis: {
get: function() {
return (known, unknown) => {
// use regex split to handle both properties and array indexing
const paths = unknown.split(/[\.(\[.+\])]+/);
let ref = known
paths.forEach(path => { if (ref) ref = ref[path] });
return ref;
}
}
},
}
}
export default {
name: 'Investment',
...
mixins: [myMixin],
computed: {
...mapState(['investment']),
participation_name() {
return this.elvis(this.investment, 'included[0].attributes.name')
}
},
...
};
최선의 해결책은 없는 것 같은데, 그냥 다 섞지 말고 그냥 아무데나 골라 써.
v-if
그러나 중첩된 속성에서 데이터를 렌더링하려는 경우에는 더 나을 수 있다.v-if="object.some.nested.property v-for="el in object.some.nested.property"
효과가 있을 것이다. 그러나 미리 계획되어 있을 것이다.object = {}
하지 않을 것이다(그것은 에러를 던질 것이다).some
정의되지 않았으며 액세스하려는 경우).
나는 너의 예처럼 어떤 가짜 데이터도 넣지 않을 것이다. 하지만 너는 ES6 클래스를 사용하여 기본 개체를 정의하고 기본 값으로 설정할 수 있다.이것은 또한 당신의 클래스 객체가 적절한 구조를 가지고 있는 한 위의 사전 정의 문제를 해결한다(그리고 그것은 또한 동의적으로 투명하고 이해하기 쉽다).
세 번째 옵션인 Getter에게 빈 데이터를 제공하는 것은 복잡할 필요가 없다. 단지 Getter를 다음과 같이 변경하십시오.
getters: {
participation: state =>
state.investment.included[0] || new DefaultParticipationObject() // I don't know what's in included array
},
이것은 사용한다.state.investment.included[0]
정의되어 있고 기본 개체인 경우.
참조URL: https://stackoverflow.com/questions/52438853/how-to-deal-with-async-data-retrieval-with-vuex-vue
'programing' 카테고리의 다른 글
정렬 가능에서 비활성화 옵션을 사용하는 방법부에 프로젝트에서 JS? (0) | 2022.05.19 |
---|---|
스프링 MVC의 컨트롤러 작업에서 외부 URL로 리디렉션 (0) | 2022.05.19 |
Vuejs에서 DOM 요소 사이의 거리를 계산하는 가장 좋은 방법은 무엇인가? (0) | 2022.05.19 |
Java에서 인터페이스 이름 지정 (0) | 2022.05.19 |
Vuex Store 모듈에서 Vue.js 플러그인 사용 (0) | 2022.05.19 |