Vuex 状态更新打破 v-for 反应性

Vuex state updates break v-for reactivity

我正在尝试使用内置的 Vuex 存储在 Nuxt 中创建一个通知组件。我有两个组件,Notifications.vueNotification.vue 来显示通知。我的商店有两个变更,一个用于添加通知,另一个用于删除通知。

以下是我项目中的相关文件:

store/notifications.js

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.js

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);

};

components/Notifications.vue

<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>

components/Notification.vue

<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 突变破坏了 Notifications.vuev-for 的反应性。我该如何解决?

好吧,缺少 反应性 是因为您确实在 data.
中获取通知 data 旨在保持静态,不会重新计算任何更改,确实如此。

在你的 Notifications.vue 文件中试试这个

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