vue.js - UI 不响应/状态更新后不重新呈现
问题描述
我构建了以下简单的 UI。
单击垃圾桶图标时,应删除书签并更新 UI,因为状态更改。进行了 API 调用,我可以在开发工具中看到该操作发生了。但是,我必须合并操作或离开页面导航,或者重新加载已删除的书签以使其不显示。我希望这可以通过使用 vuex 的 mapState 助手来实现。
下面是相关部分。
查看(对不起,这有点乱)-这实际上是未删节的版本:
<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>
店铺:
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;
api服务:
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);
之后立即执行commit('SET_BOOKMARKS', bookmarks);
不会导致发生任何更改,因为您只是分配了相同的对象实例。最好编写一个REMOVE_BOOKMARK
突变来处理这个问题,这样您就不会在突变之外更改 Vuex 状态。
推荐阅读
- javascript - 为什么 django 上的“关注”按钮不起作用?
- android - 使用直接标记化的 Google Pay 付款集成
- python - 使用 csv 文件从考勤日志报告中过滤时间
- python - 启动 VSCode 时自动激活 conda 环境
- python - 如何过滤数据库表行并更新 django 中的特定列?
- javascript - Bootstrap4:卡片标题和导航在一行
- asp.net-core - ASP.Net Core - Toast 通知未显示在已部署的应用程序上
- java - 是否可以使用 Citrus-Framwork 将 http-response 的内容类型作为字符串获取?
- c# - LinkButtons 在图标周围的可点击区域表现不同(我不认为这是前端问题)
- python - 将 Numpy 数组转换为视频(mp4)