source

Vuex 상태 업데이트로 인해 v-for reactivity가 중단됨

lovecheck 2023. 1. 12. 22:09
반응형

Vuex 상태 업데이트로 인해 v-for reactivity가 중단됨

빌트인 Vuex 스토어를 사용하여 Nuxt에서 Notification 컴포넌트를 만들려고 합니다.난 두 개의 구성 요소가 있어Notifications.vue그리고.Notification.vue알림을 표시합니다.내 스토어에는 알림 추가용과 제거용 두 개의 돌연변이가 있습니다.

프로젝트 관련 파일은 다음과 같습니다.

스토어/알림.개요

export const state = () => ({
    notifications: []
});

export const getters = {
    allNotifications: state => state.notifications
};

export const mutations = {
    PUSH_NOTIFICATION(state, notification) {
        state.notifications.push(notification);
    },
    REMOVE_NOTIFICATION(state, notificationToRemove) {
    // PROBLEM ---> Updates state but breaks reactivity
        state.notifications = [
            ...state.notifications.filter(notification => notification.id != notificationToRemove)
        ];
};

export const actions = {
    async pushNotification({ commit }, notification) {
        return new Promise((resolve, reject) => {
            notification = {
                ...notification,
                id: (Math.random().toString(36) + Date.now().toString(36)).substr(2)
            };
            commit('PUSH_NOTIFICATION', notification);
            resolve(notification.id);
        });
    },
    async removeNotification({ commit }, id) {
        return new Promise((resolve, reject) => {
            commit('REMOVE_NOTIFICATION', id);
            resolve();
        });
    }
};

plugins/notifications.module

export default ({ store }, inject) => {
    let notifications = {
        async notify(notification) {
            return await store.dispatch('notifications/pushNotification', notification);
        },
        async removeNotification(id) {
            console.log(`The notification with the id ${id} will be removed!`);
            await store.dispatch('notifications/removeNotification', id);
            return true;
        }
    };
    // This allows me to access the methods above from any component like `this.$notifications`
    inject('notifications', notifications);

};

컴포넌트/알림.표시하다

<template>
    <div class="notifications">
        <button @click="test()">Notify</button><!-- This is to test adding new notifications -->
        <div class="notification-bounds">
            <Notification v-for="notification in notifications" :key="notification.id" :id="notification.id">{{ notification.content }}</Notification>
        </div>
    </div>
</template>

<script>
    export default {
        data() {
            return {
                notifications: this.$store.getters['notifications/allNotifications']
            };
        },
        methods: {
            test() {
                // This works therefore `PUSH_NOTIFICATION` does not break reactivity
                this.$notifications.notify({ content: 'Test' }); 
            }
        }
    };
</script>

컴포넌트/알림표시하다

<template>
    <div class="notification">
        <slot></slot>
        <button @click="close()">Close</button>
    </div>
</template>

<script>
    export default {
        props: [
            'id'
        ],
        methods: {
            close(){
    // PROBLEM ---> This updates the state internally but it breaks reactivity so 
    // there is something wrong with the `REMOVE_NOTIFICATION` mutation.
                this.$notifications.removeNotification(this.id) 

            }
        }
    };
</script>

문제는 이 시스템이REMOVE_NOTIFICATION돌연변이는 반응성을 깨뜨린다v-forNotifications.vue이거 어떻게 풀지?

네, 반응성이 낮다는 것은 알림을 수신할 수 없기 때문입니다.data.
data정적인 것을 목표로 하고 있으며 실제로 변경을 재계산하지 않습니다.

이거 한번 입어봐Notifications.vue파일

<script>
export default {
  computed: {
    notifications() {
      return this.$store.getters['notifications/allNotifications']
    },
  },
}
</script>

언급URL : https://stackoverflow.com/questions/68725711/vuex-state-updates-break-v-for-reactivity

반응형