programing

Vue.js, Vuex, Vuex 저장소의 데이터가 변환될 때 컴포넌트 뷰가 반응하지 않음(알 수 없는 예외 포함)

newsource 2022. 7. 31. 23:05

Vue.js, Vuex, Vuex 저장소의 데이터가 변환될 때 컴포넌트 뷰가 반응하지 않음(알 수 없는 예외 포함)

Vuex를 처음 사용하는데 $store에서 관리되는 searchResults 어레이와 관련된 문제, 특히 스토어가 변환되었을 때 SearchResults 뷰 컴포넌트가 반응하지 않는 이유 때문에 당황했습니다.

송신하면 검색 기능(믹스인)을 기동해, 스토어의 searchResults 배열을 갱신하는 액션을 디스패치 해, ViewSearchResults를 로드하는 검색 폼 컴포넌트가 있습니다.vue - 검색 결과가 표시되는 곳 - 작동 중입니다.

다음으로 ViewSearchResults 입니다.vue에는 검색 양식 구성 요소도 포함되어 있으며 이후 검색이 실행되면 다시 검색 기능이 성공적으로 실행되며 저장소가 그에 따라 업데이트됩니다. 그러나 ViewSearchResults.vue가 스토어의 변경에 응답하지 않음(업데이트 라이프 사이클이 실행되지 않음) 때문에 새로운 검색 결과를 사용할 수 없음)

...그리고 디버깅 과정에서 템플릿에 스토어에 대한 참조를 추가함으로써 이를 발견했습니다.{{ this.$store.state.searchResults.length }}뷰가 갱신되고 새로운 데이터가 사용 가능하며 이후 검색이 정상적으로 뷰를 갱신합니다.

지금까지 Vue.js를 사용해 본 경험으로는 설명이 되지 않습니다.누가 이걸 좀 밝혀줄 수 있나요? 어떻게 하면 제 마크업을 오염시키지 않고 원하는 결과를 얻을 수 있을까요?

미리 감사 드려요.

관련 검색 믹스인 발췌:

export default {
    created: function() {},
    methods: {
        doSearch: function(term) {
            const searchTerm = term.toLowerCase();
            this.$store.dispatch("setSearchTerm", term);
            let searchResults = [];
            // SNIP: search (iterate) a bunch of .json data ...
            searchResults.push(searchResult); // searchResults array CONFIRMED √
            this.$store.dispatch("setSearchResults", searchResults);
        }
    }
}

스토어의 관련 발췌:

export default new Vuex.Store({
    strict: true,
    state: {
        searchTerm: "",
        searchResults: [],
    },
    mutations: {
        setSearchTerm(state, payload) {
            state.searchTerm = payload;
        },
        setSearchResults(state, payload) {
            console.log(payload); // √ confirmed: updated array is there
            state.searchResults = payload;
            console.log(state.searchResults); // √ confirmed: updated array is there
        }
    },
    getters: {
    },
    actions: {
        // dispatched in the search mixin
        setSearchTerm(context, payload){
            context.commit("setSearchTerm", payload);
        },
        setSearchResults(context, payload) {
            context.commit("setSearchResults", payload);
        }
    },
    modules: {
    }
})

...및 ViewSearchResults.vue(관련 발췌):

// IF I LEAVE THIS IN, BOB'S YOUR UNCLE ... WITHOUT IT, THE VIEW DOESN'T REACT
<div style="display: none;">this.$store.state.searchResults: {{ this.$store.state.searchResults.length }}</div>

<ul class="search-results">
    <li v-for="(imgObj, ix) in searchResults" :key="ix">
        <img :src="require('@/assets/img/collections/' + imgObj.path + '/' + imgObj.data + '/' + imgObj.imgFile)" alt="" />
    </li>
</ul>
export default {
    components: {
        // 'app-search' occurs elswhere in the app, but when submitted, loads this ViewSearchResults, search component still present
        'app-search': SearchForm
    },
    props: {
    },
    data() {
        return {
            searchTerm: "",
            searchResults: []
        }
    },
    created: function() {
        // only becuz refresh
        if (!this.searchTerm) {
            this.searchTerm = this.$route.params.searchTerm;
        }
        console.log(this.$store.state.searchResults.length); // 0 if refreshed, ERGO:
        this.$store.state.searchResults.length ? this.searchResults = this.$store.state.searchResults : this.searchResults = JSON.parse(localStorage.getItem("searchResults"));
        console.log(this.searchResults); // searchResults √
    },
    updated: function() {
        // ?!?!?! WHY DOES THIS FIRE ONLY IF I LEAVE THE REFERENCE TO THE STORE IN THE TEMPLATE? {{ this.$store.state.searchResults.length }}
        this.$store.state.searchTerm ? this.searchTerm = this.$store.state.searchTerm : this.searchTerm = localStorage.getItem("searchTerm");
        this.$store.state.searchResults.length ? this.searchResults = this.$store.state.searchResults : this.searchResults = JSON.parse(localStorage.getItem("searchResults"));
    },
    computed: {
    },
    mounted: function() {},
    mixins: [ Search ]
}

다시 한 번 통찰해 주셔서 감사합니다.

위스키 T

컴포넌트에 업데이트가 없기 때문에 이 컴포넌트를 실행할 필요가 없습니다.update갈고리를 채우다

실제로 저장소의 값에 따라 성분이 결정되기를 원하는 것 같습니다.

Vuex 가이드의 권장 사항에 따라 설정합니다.

computed: {
  searchResults () {
    return this.$store.state.searchResults
  }
},
created () {
  this.doSearch(this.$route.params.searchTerm)
}

필요에 따라서 헬퍼를 사용할 수도 있습니다.

computed: mapState(['searchResults']),

로컬 스토리지에서 데이터를 로드하는 부분은 스토어 상태 이니셜라이저에서 수행해야 합니다.

let initialSearchResults
try {
  initialSearchResults = JSON.parse(localStorage.getItem('searchResults'))
} catch (e) {
  console.warn('Could not parse saved search results')
  initialSearchResults = []
}

export default new Vuex.Store({
  strict: true,
  state: {
    searchTerm: "",
    searchResults: initialSearchResults
  },

언급URL : https://stackoverflow.com/questions/62014467/vue-js-vuex-component-view-not-reacting-when-data-in-the-vuex-store-is-mutated