[英]Vue and Vuex: computed property isn't called when changing state
I'm quite new with Vue and Vuex so please bear with me.我对 Vue 和 Vuex 很陌生,所以请多多包涵。
I want to make the computed function versions()
get called when I change state.template
, but I'm failing to do so.我想在更改
state.template
时调用计算的 function versions()
,但我没有这样做。 More specifically, when state.template.versions
changes.更具体地说,当
state.template.versions
发生变化时。
This is part of the component that I want to re-render when state.template.versions
changes.这是当
state.template.versions
更改时我想要重新渲染的组件的一部分。 You can also see the computed property versions()
which I want to be called:您还可以看到我想要调用的计算属性
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
})
},
This is the getter
:这是
getter
:
documentVersions (state) {
return state.template ? state.template.versions : []
},
This is the action
:这是
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)
})
This is the mutation
:这是
mutation
:
template (state, template) {
state.template = template
},
I've read that there are some cases in which Vue doesn't detect chanegs made to an array, but .push()
seems to be detected.我读过在某些情况下 Vue 没有检测到对数组进行的更改,但似乎检测到了
.push()
。 Source: https://v2.vuejs.org/v2/guide/list.html#Caveats来源: https://v2.vuejs.org/v2/guide/list.html#Caveats
Any idea on why the computed property is not being called when I update context.state.template.versions
?关于我更新
context.state.template.versions
时为什么不调用计算属性的任何想法?
The issue may come from state.template = template
.问题可能来自
state.template = template
。 You guessed correctly that it was a reactivity issue, but not from the Array reactivity, but the template
object.你猜对了,这是一个反应性问题,但不是来自阵列反应性,而是
template
object。
Vue cannot detect property addition or deletion. Vue 无法检测到属性添加或删除。 This includes affecting a complex object to a property.
这包括将复杂的 object 影响到属性。 For that, you need to use
Vue.set
.为此,您需要使用
Vue.set
。
So your mutation should be:所以你的突变应该是:
template (state, template) {
Vue.set(state, "template", template)
},
https://v2.vuejs.org/v2/guide/reactivity.html#Change-Detection-Caveats https://v2.vuejs.org/v2/guide/reactivity.html#Change-Detection-Caveats
I think this error occurred because you did not declare your store state correctly.我认为发生此错误是因为您没有正确声明您的商店 state。 Make sure you have the
versions
property in your template
object.确保您的
template
object 中有versions
属性。
state: {
template: {
versions: []
}
}
This way, any changes in the versions
property will be detected by vue.这样,vue 将检测到
versions
属性中的任何更改。
Your function won't get called because this is wrong:您的 function 不会被调用,因为这是错误的:
context.state.template.versions.push(data)
context.commit('template', context.state.template)
the context.state
object just points to your current state nothing more. context.state
object 仅指向您当前的 state 仅此而已。
My suggested solution will be:我建议的解决方案是:
First You need to declare your store state correctly首先您需要正确声明您的商店 state
state: { template: { versions: [] } }
You need to update your getter to look like this with no unnecessary conditioning:您需要更新您的吸气剂,使其看起来像这样,没有不必要的条件:
documentVersions: state => return state.template.versions,
add a new mutation添加一个新的突变
ADD_VERSION: (state, version) => { state.template = {...state.template, versions: [...state.template.versions, version] }; }
your action should like this now:你的动作现在应该是这样的:
createProductionVersion({commit}, data) { return new Promise((resolve, reject) => { documentsService.createProductionVersion(data).then(result => { commit('ADD_VERSION', data); resolve(result); }); }); }
In your component I suggest to change your computed property from a function to an object that contains a get
and set
methods ( set
is optional)在您的组件中,我建议将您的计算属性从 function 更改为包含
get
和set
方法的 object( set
是可选的)
versions: { get() { return this.documentVersions.map(function (version) { const v = { id: version.id, name: 'Draft Version', effectiveDate: '', status: 'Draft version', } return v }) } },
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.