Vuex 状态更新打破 v-for 反应性
Vuex state updates break v-for reactivity
我正在尝试使用内置的 Vuex 存储在 Nuxt 中创建一个通知组件。我有两个组件,Notifications.vue
和 Notification.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.vue
中 v-for
的反应性。我该如何解决?
好吧,缺少 反应性 是因为您确实在 data
.
中获取通知
data
旨在保持静态,不会重新计算任何更改,确实如此。
在你的 Notifications.vue
文件中试试这个
<script>
export default {
computed: {
notifications() {
return this.$store.getters['notifications/allNotifications']
},
},
}
</script>
我正在尝试使用内置的 Vuex 存储在 Nuxt 中创建一个通知组件。我有两个组件,Notifications.vue
和 Notification.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.vue
中 v-for
的反应性。我该如何解决?
好吧,缺少 反应性 是因为您确实在 data
.
中获取通知
data
旨在保持静态,不会重新计算任何更改,确实如此。
在你的 Notifications.vue
文件中试试这个
<script>
export default {
computed: {
notifications() {
return this.$store.getters['notifications/allNotifications']
},
},
}
</script>