相关数据更改后,Vue 组件不会立即更新

Sas*_*M78 7 vue.js vuejs2

我仍然是 Vue 的新手,并且在连接数据更新后立即让组件更新其内容。组件将在重新渲染后立即显示更改的内容。

成分

Vue.component('report-summary', {
  props: ['translation', 'store'],
  watch: {
    'store.state.currentModel.Definition': {
      handler: function(change) {
        console.log('Change detected', change);
      },
      deep:true
    }
  },
  template: '<div>
    '<div class="alert alert-secondary" role="alert">' +
    '<h5 class="border-bottom border-dark"> {{ translation.currently_defined }}</h5>' +
    '<div>{{ store.state.currentModel.Definition.length }} {{translation.elements }}</div>' +
    '</div>' +
    '</div>'
});
Run Code Online (Sandbox Code Playgroud)

store 作为页面 HTML 中的属性传入:

<report-summary :translation="t" :store="store"></report-summary>
Run Code Online (Sandbox Code Playgroud)

store本身是一个Vuex.Store

let store = new Vuex.Store({
  state: {
    t: undefined,
    currentModel: undefined
  },
  mutations: {
    storeNewModel(state) {
      let model = CloneFactory.sealedClone(
        window.Project.Model.ReportTemplateModel);
      model.Header = CloneFactory.sealedClone(
        window.Project.Model.ReportTemplateHeaderModel);
      state.currentModel = model;
    },
    storeNewModelDefinition(state, definition) {
     state.currentModel.Definition.push(definition);
    }
  }
});
Run Code Online (Sandbox Code Playgroud)

currentModelstore.commit('storeNewModel');任何数据存储在模型的Definition属性中之前,通过调用来初始化元素。

通过store.commit('storeNewModelDefinition')在循环中使用来更新定义的内容:

for (let c in this.$data.currentDefinition.charts) {
  store.commit('storeNewModelDefinition', c);
}
Run Code Online (Sandbox Code Playgroud)

store.commit('storeNewModelDefinition', c);被调用时,商店会按预期更新:

Vuex%20Store|325x190

但是组件不会对更改的数据做出反应:

未%20更新|553x110

然后,当我离开(通过更改隐藏嵌入组件的视图)并再次导航到视图时,内容已更新:

更新|476x112

在控制台窗口中,我看到观察者在任何时间点都没有被触发:

控制台|681x133

我在这里缺少什么?非常感谢您提前打开我的眼睛。

使用事件总线

切换watch到事件总线侦听器也没有按计划工作。

这是 EventBus 的初始化:

window.eventBus= new Vue(); 
Run Code Online (Sandbox Code Playgroud)

我将此添加到我的组件中:

  created: function() {
    window.eventBus.$on('report-summary-update', function() {
      this.$nextTick(function(){ this.$forceUpdate(); });
    });
  }
Run Code Online (Sandbox Code Playgroud)

并在从列表中添加或删除元素后发出事件:

window.eventBus.$emit('report-summary-update');
Run Code Online (Sandbox Code Playgroud)

在调试器中设置断点时,this.$forceUpdate();我看到它也被调用,但 UI 仍然会显示旧内容而没有任何更改。我现在真的很失落。


PS 我在Vue 论坛上交叉发布了这个,但由于社区很小,希望在这里收到一些反馈。

Ank*_*nte 2

将数据推送到嵌套数组总是会导致组件不更新的问题。

尝试向您的商店添加一个 getter 并使用该 getter 从商店获取数据

let store = new Vuex.Store({
  state: {
    t: undefined,
    currentModel: undefined
  },
  mutations: {
    storeNewModel(state) {
      let model = CloneFactory.sealedClone(
        window.Project.Model.ReportTemplateModel);
      model.Header = CloneFactory.sealedClone(
        window.Project.Model.ReportTemplateHeaderModel);
      state.currentModel = model;
    },
    storeNewModelDefinition(state, definition) {
     state.currentModel.Definition.push(definition);
    }
  },
  getters:{
    definitions(state){
      return state.currentModel.Definition
    }
  }
});
Run Code Online (Sandbox Code Playgroud)

在您的组件中,您可以添加一个计算属性来从存储中获取数据

Vue.component('report-summary', {
  props: ['translation', 'store'],
  computed: {
    definitions(){
     return store.getters.definitions
    }
  },
  template: '<div>
    '<div class="alert alert-secondary" role="alert">' +
    '<h5 class="border-bottom border-dark"> {{ translation.currently_defined }}</h5>' +
    '<div>{{ definitions.length }} {{translation.elements }}</div>' +
    '</div>' +
    '</div>'
});
Run Code Online (Sandbox Code Playgroud)

更新(2019 年 11 月 30 日) 如果上述代码仍然不起作用,请将您的storeNewModelDefinition突变更改为:

storeNewModelDefinition(state, definition) {
     // Create a new copy of definitions
     let definitions = [...state.currentModel.Definition]

     // Push the new item
     definitions.push(definition)

     // Use `Vue.set` so that Vuejs reacts to the change
     Vue.set(state.currentModel, 'Definition', definitions);
    }
Run Code Online (Sandbox Code Playgroud)