我构建了以下简单的UI。
在点击垃圾桶图标时,由于状态改变,书签应该被删除,UI也会更新。API调用已经完成,我可以在开发工具中看到该动作的发生。然而,我必须合并该动作,或者导航离开页面,或者进行硬重载,才能使删除的书签不显示出来。我希望通过使用vuex的mapState helper来解决这个问题。
以下是相关部分。
view(抱歉,这个有点乱)--这其实是未删减的版本。
<template>
<div>
<v-card class="mx-auto" max-width="700">
<v-list two-line subheader>
<v-subheader>Bookmarks</v-subheader>
<v-list-item
v-for="obj in Object.entries(bookmarks).sort((a, b) => {
return a[1].paragraph - b[1].paragraph;
})"
:key="obj[0]"
>
<v-list-item-avatar>
<v-icon @click="goTo(obj)">mdi-bookmark</v-icon>
</v-list-item-avatar>
<v-list-item-content @click="goTo(obj)">
<v-list-item-title>
{{ obj[0].split('/')[1] + ' by ' + obj[0].split('/')[0] }}
</v-list-item-title>
<v-list-item-subtitle>
Part {{ obj[1].part + 1 }}, paragraph {{ obj[1].paragraph + 1 }}
</v-list-item-subtitle>
</v-list-item-content>
<v-list-item-action>
<v-btn icon>
<v-icon @click="deleteBookmark(obj[0])" title="Remove bookmark"
>mdi-delete</v-icon
>
</v-btn>
</v-list-item-action>
</v-list-item>
</v-list>
</v-card>
</div>
</template>
<script>
import { mapState, mapActions } from 'vuex';
export default {
computed: {
...mapState(['bookmarks'])
},
methods: {
...mapActions(['deleteBookmark']),
goTo(obj) {
const [authorName, title] = obj[0].split('/');
this.$router.push({
name: 'showText',
params: {
authorName,
title
},
query: { part: obj[1].part, paragraph: obj[1].paragraph }
});
}
}
};
</script>
store:
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
import apiService from '@/services/ApiService';
const store = new Vuex.Store({
state: {
bookmarks: {}
},
mutations: {
SET_BOOKMARKS(state, bookmarks) {
state.bookmarks = bookmarks;
}
},
actions: {
async deleteBookmark({ commit, state }, key) {
let { bookmarks } = state;
const response = await apiService.deleteBookmark(key);
delete bookmarks[key];
commit('SET_BOOKMARKS', bookmarks);
return response;
}
}
});
export default store;
apiService。
import axios from 'axios';
const apiClient = axios.create({
baseURL: process.env.VUE_APP_API_URL,
withCredentials: true,
headers: {
Accept: 'application/json',
'Content-Type': 'application/json'
},
responseType: 'json'
});
export default {
deleteBookmark(key) {
return apiClient.delete(`/api/bookmarks/${key}`);
}
};
红旗就在这里。
delete bookmarks[key];
请阅读 变化检测注意事项.
使用 Vue.delete
而不是。
Vue.delete(bookmarks, key);
Doing commit('SET_BOOKMARKS', bookmarks);
后,不会导致任何变化发生,因为你只是在分配同一个对象实例。最好的办法是写一个 REMOVE_BOOKMARK
突变来处理这个问题,所以你不会在突变之外改变Vuex的状态。