vue.js - Vue 计算属性不响应状态变化
问题描述
我无法弄清楚为什么在调用该方法details
时以下组件中的计算属性没有更新:fetch()
<template>
<div>
{{ haveData }} //remains undefined
</div>
</template>
<script>
export default {
props: {
group: {
type: Object,
required: true
},
},
computed: {
currentGroup() {
return this.$store.getters['user/navbar_menu_app_current_group'](
this.group.id
)
/*-- which is the following function
navbar_menu_app_current_group: state => item => {
return state.menu.find(m => {
return m.id == item
})
}
*/
/*-- this function returns an object like so
{
id: 1,
label: 'kity cats',
}
***details --> IS NOT DEFINED. If I add it to the current group as null, my problem goes away. However, this is a previous API call that does not set the `details` parameter.
*/
},
details() {
let c = this.currentGroup.details
console.log(c) // returns undefined, which makes sense, but it should be updated after this.fetch() is called
return c
},
haveData() {
return this.details != null
}
},
methods: {
async fetch() {
await this.$store.dispatch(
'user/navbar_menu_app_details_get',
this.group.id
)
//This is setting the "details" part of the state on menu which is referred to in the computed properties above
//Previous to this there is no state "this.group.details"
//If I add a console log to the mutation the action calls, I get what is expected.
}
},
created() {
if (!this.haveData) {
this.fetch()
}
}
}
</script>
如果我将数组项更改为 include details
,它可以工作:
{
id: 1,
label: 'kity cats',
details: null // <-- added
}
不幸的是,该数组是从大型 API 调用创建的,并且添加details
似乎是不必要的,因为它可能永远不需要。
如何在不添加details:null
默认状态的情况下使计算属性正常工作?
尝试1:
// Vuex mutation
navbar_menu_app_details_set(state, vals) {
let app = state.menu.find(item => {
return item.id == vals[0] //-> The group id passing in the dispatch function
})
//option 1 = doesn't work
app = { app, details: vals[1] } //-> vals[1] = the details fetched from the action (dispatch)
//option 2 = doesnt work
app.details = vals[1]
//option 3 = working but want to avoid using Vue.set()
import Vue from 'vue' //Done outside the actual function
Vue.set( app, 'details', vals[1])
},
尝试2:
// Vuex action
navbar_menu_app_details_get(context, id) {
return new Promise((resolve, reject) => {
setTimeout(() => {
context.commit('navbar_menu_app_details_set', [
context.getters.navbar_menu_app_current(id), //-> the same as find function in the mutation above
apps[id]
])
resolve()
}, 1000)
})
}
// --> mutation doesn't work
navbar_menu_app_details_set(state, vals) {
vals[0].details = vals[1]
},
解决方案
Vue 实例可通过 Vuex 突变获得this._vm
,您可以使用vm.$set()
(等效于Vue.set()
)添加details
到菜单项:
navbar_menu_app_details_set(state, vals) {
let app = state.menu.find(item => {
return item.id == vals[0]
})
this._vm.$set(app, 'details', vals[1])
},
推荐阅读
- unit-testing - 如何重写 gocov 命令去工具覆盖?
- java - 片段包
- c# - ASP.NET Core Web API 中的 Azure AD 仅应用身份验证
- reactjs - 在展示/容器模式中使用 PureComponents
- javascript - 如何自定义 vaadin-upload 聚合物组件的结果?
- javascript - 如何从角度通用构建中删除 sourceMappingURL?
- postgresql - PostgreSQL 本地时间
- mysql - 按组中的最大值排序
- c - 使用 C 编译 DLL
- python - Datetime Pandas 函数仅转换单个系列