为啥这个 Vue 计算属性不是响应式的?
Posted
技术标签:
【中文标题】为啥这个 Vue 计算属性不是响应式的?【英文标题】:Why is this Vue computed property not reactive?为什么这个 Vue 计算属性不是响应式的? 【发布时间】:2019-07-09 23:08:02 【问题描述】:我希望我的视图使用作为道具传递的 id 在商店中查找对象的属性。存储中的对象异步显示,因此该对象可能不会立即出现。我希望视图对对象的最终外观做出反应。
<template>
<div>
<h1> title </h1>
</div>
</template>
<script>
export default
props: ['id'],
computed:
widget ()
let path = `widget/$this.id`
return this.$store.state.widgets[path]
,
title ()
let widget = this.widget
return (widget) ? widget.data().fullName : 'nothing to see here'
</script>
使用 vuex 调试工具,我可以看到商店小部件对象一开始是空的,然后设置为 widgets: 'widgets/someId': ...
,但我的 vue 似乎没有接受更改。标题仍然 == 'nothing...'。
我尝试制作这些方法,但我得到了相同的行为。我还尝试替换商店中的整个 widgets
对象,而不是一次替换一个道具(我认为这是一个要求),但仍然没有运气。
我认为我的问题与this one 非常相似,但那里的答案过于简洁。它只是说“使用数据项”,但我真的不知道那是什么或如何使用它(或者为什么这会使 vue 反应)。
【问题讨论】:
你能显示小部件的 vuex 存储代码吗? 你考虑过使用getters吗?它们的优点是仅根据商店变化进行重新评估。您可以使用公开其他吸气剂的第二个参数“链接”吸气剂。您可以根据各自计算的widget
评估title
。 ***.com/a/53993174/5059657
是的,计算属性不是很被动。前段时间我遇到了同样的问题。我最终使用了watchers
:vuejs.org/v2/guide/computed.html#Watchers
@AlexanderStaroselsky - 我确实尝试了一个具有相同结果的吸气剂。我认为原因是我的 getter 需要一个参数(path
),所以我的 getter 需要返回一个函数,并且(也许??)阻止它反应?
【参考方案1】:
您的小部件很可能没有反应,因为widget
本身不会改变,widget.data
也不会改变,因为它是您定义的函数。 Vue 在调用data
时不会“看到”数据的变化,因为它是一个函数。
您有多种方法可以使您的小部件具有响应性。一种是预先计算您的数据并返回一个没有函数的对象。当您拥有大量小部件时,这可能意味着性能下降,即使您不需要其中的大部分数据。
另一个可能是使用相对较新的getter 函数/方法。您将使用 widget.data
获取数据并拥有类似
id: 1,
get data()
// Whatever was in your function before
请记住,这是(我相信)Ecmascript 6 的一项功能,因此您可能需要通过 babel 运行它才能与所有相关浏览器兼容。
【讨论】:
谢谢。我被那个 data() 函数困住了,因为这些对象来自 google firestore。事实证明,使用 Vue.set() 足以让我的 vue 看到变化(并再次调用 data() 函数)。【参考方案2】:Mutations Follow Vue's Reactivity Rules
由于您看到它从空置到有一些成员,因此您正在与 Vue 的 change detection caveats 发生冲突。
Vue 无法检测到属性添加或删除。
添加或删除成员时需要使用Vue.set
,即使在Vuex中也是如此。
【讨论】:
谢谢。那解决了它!澄清一下,我的商店设置器中有几段代码写着state.someWidget.someProp = 'foobar'
。要变得被动,我应该将所有这些更改为Vue.set(state.someWidget, 'someProp', 'foobar')
吗??
如果您设置的属性已经存在,它将是反应性的。如果添加或删除属性(在创建包含对象之后),则只需要 set
。以上是关于为啥这个 Vue 计算属性不是响应式的?的主要内容,如果未能解决你的问题,请参考以下文章