用户界面不响应/状态更新后不会重新呈现

时间:2020-04-23 23:37:31

标签: vue.js vuex vuetify.js

我构建了以下简单的用户界面。

screenshot of UI

在单击废纸icon图标时,由于状态更改,应该删除书签并更新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;

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

1 个答案:

答案 0 :(得分:2)

红旗在这里:

delete bookmarks[key];

请阅读Change Detection Caveats

改为使用Vue.delete

Vue.delete(bookmarks, key);

在此之后立即执行commit('SET_BOOKMARKS', bookmarks);不会导致任何更改,因为您只是分配了相同的对象实例。最好编写一个REMOVE_BOOKMARK突变来处理此问题,以免在突变之外更改Vuex状态。