Vue 中的计算属性不会触发监视
Posted
技术标签:
【中文标题】Vue 中的计算属性不会触发监视【英文标题】:Computed property in Vue is not triggering a watch 【发布时间】:2018-12-29 18:32:48 【问题描述】:根据this post,观察计算属性应该不是问题。然而我的代码却不能正常工作。
<template>
<div v-if="product" class="section">
<form>
<div class="control"><input type="text" class="input" v-model="title"></div>
<div class="control"><input type="text" class="input" v-model="description"></div>
</form>
</div>
</template>
<script>
export default
data()
return
title: null,
description: null
,
computed:
product()
// const payload = collection: 'products', id: this.$route.params.productId
// return this.$store.getters.objectFromId(payload)
console.log('working')
return title: 'Awesome Title', description: 'Awesome Description'
,
watch:
product()
this.title = this.product.title,
this.description = this.product.description
</script>
我希望watch
在product
返回时触发,但它没有。
我可以像这样在计算属性中设置属性:
computed:
product()
const payload = collection: 'products', id: this.$route.params.productId
const product = this.$store.getters.objectFromId(payload)
this.title = product.title
this.description = product.description
return product
但是编译器给了我一个警告:error: Unexpected side effect in "product" computed property
【问题讨论】:
你想达到什么目的?您的问题可能有更直接的解决方案 我已更新我的帖子以更清楚地显示意图。我正在尝试获取产品并设置一些绑定到某些表单输入的初始数据()。我可以在计算函数中设置值,但我在编译器中收到了这个烦人的副作用警告。我认为在 get 中设置属性是不好的做法? 您需要设置use a watcher 并设置immediate
才能让您的观察者在初始渲染时触发。
@HamishJohnson 您不为此使用计算。看看创建/安装的 vue.js 钩子。在它们内部,您可以加载外部数据并将其附加到当前数据模型
@Enrico 是的,我必须同意你的观点——不太清楚为什么我在这种情况下选择了计算。谢谢
【参考方案1】:
尝试以下方法:
watch:
product:
immediate: true,
handler(value)
updateCode();
【讨论】:
【参考方案2】:根据 OP 的 cmets,他的意图是获取和加载一些初始数据。
实现此行为的常用方法是将其放在 created or mounted
vuejs 生命周期钩子中。
<template>
<div v-if="product" class="section">
<form>
<div class="control"><input type="text" class="input" v-model="title"></div>
<div class="control"><input type="text" class="input" v-model="description"></div>
</form>
</div>
</template>
<script>
export default
data()
return
title: '',
description: ''
,
created()
this.getInitialData();
this.foo();
console.log("created!");
,
methods:
getInitialData: function()
const payload =
collection: 'products',
id: this.$route.params.productId
;
var product = this.$store.getters.objectFromId(payload);
this.title = product.title;
this.description = product.description;
,
foo: function()// ...
,
</script>
【讨论】:
【参考方案3】:你的结构有点乱。 product
是一个计算值,因此只要它的源值发生变化,它就会运行。 (你无法控制它何时运行。)它不应该有副作用(分配this.description
、this.title
)或触发网络请求。
product
中的代码正在获取您的源数据。这属于methods
,明确链接到用户操作或生命周期事件。
为什么需要复制数据(watch:product
中的this.description = product.description
)?当你的数据(你的应用程序状态)在 Vue 之外时,Vue 工作得最好,在一个全局变量中。然后,您的 Vue 组件将透明地反映应用程序在给定时刻的状态。
希望这会有所帮助。
【讨论】:
以上是关于Vue 中的计算属性不会触发监视的主要内容,如果未能解决你的问题,请参考以下文章