Vue和Vuex:更改状态时不调用计算属性

时间:2020-08-07 10:08:11

标签: javascript vue.js vuex

我对Vue和Vuex很陌生,所以请忍受我。

我想在更改d时调用计算函数versions(),但是我没有这样做。更具体地说,当state.template发生变化时。

这是我要在state.template.versions更改时重新呈现的组件的一部分。您还可以看到我想称为的计算属性state.template.versions

versions()

这是 <el-dropdown-menu class="el-dropdown-menu--wide" slot="dropdown"> <div v-for="version in versions" :key="version.id"> ... </div> </el-dropdown-menu> ... computed: { ...mapState('documents', ['template', 'activeVersion']), ...mapGetters('documents', ['documentVersions', 'documentVersionById', 'documentFirstVersion']), versions () { return this.documentVersions.map(function (version) { const v = { id: version.id, name: 'Draft Version', effectiveDate: '', status: 'Draft version', } return v }) },

getter

这是 documentVersions (state) { return state.template ? state.template.versions : [] },

action

这是 createProductionVersion (context, data) { return new Promise((resolve, reject) => { documentsService.createProductionVersion(data).then(result => { context.state.template.versions.push(data) // <-- Here I'm changing state.template. I would expect versions() to be called context.commit('template', context.state.template) resolve(result) })

mutation

我已经读到,在某些情况下,Vue无法检测到对数组进行的更改,但是似乎可以检测到 template (state, template) { state.template = template }, 。来源:https://vuejs.org/v2/guide/list.html#Caveats

关于更新.push()时为何不调用计算属性的任何想法吗?

3 个答案:

答案 0 :(得分:2)

问题可能来自winfo_reqheight()。您正确地猜到这是一个反应性问题,但不是来自Array反应性,而是state.template = template对象。

Vue无法检测到属性的添加或删除。这包括将复杂对象影响到属性。为此,您需要使用template

所以您的突变应该是:

Vue.set

GitHub issue

答案 1 :(得分:1)

我认为发生此错误是因为您没有正确声明存储状态。确保您的versions对象中具有template属性。

state: {
  template: {
    versions: []
  }
}

这样,vue将检测到versions属性中的任何更改。

答案 2 :(得分:1)

您的函数将不会被调用,因为这是错误的:

context.state.template.versions.push(data) 
context.commit('template', context.state.template)

context.state对象仅指向您当前的状态。

我建议的解决方案是:

  1. 首先,您需要正确声明商店状态

    state: {
       template: {
          versions: []
       }
    }
    
  2. 您需要更新您的吸气剂,使其看起来像这样,没有不必要的 条件:

    documentVersions: state => return state.template.versions,

  3. 添加新的突变

     ADD_VERSION: (state, version) => {
       state.template = {
         ...state.template,
         versions: [...state.template.versions, version]
        };
      }
    
  4. 您的操作现在应该是这样的:

       createProductionVersion({commit}, data) {
           return new Promise((resolve, reject) => {
             documentsService.createProductionVersion(data).then(result => {
               commit('ADD_VERSION', data);
               resolve(result);
             });
           });
         }
    
  5. 在您的组件中,我建议从函数更改您的计算属性 到包含getset方法的对象(set是可选的)

    versions: {
      get() {
        return this.documentVersions.map(function (version) {
          const v = {
            id: version.id,
            name: 'Draft Version',
            effectiveDate: '',
            status: 'Draft version',
          }
          return v
        })
      }
    },