简体   繁体   English

Vue 中的计算属性不会触发监视

[英]Computed property in Vue is not triggering a watch

According to this post , it shouldn't be a problem to watch a computed property.根据这篇文章,观看计算属性应该不是问题。 And yet my code isn't working.然而我的代码不起作用。

<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>

I'm expecting the watch to trigger when product is returned, but it doesn't.我希望watchproduct退回时触发,但事实并非如此。

I could set the properties in the computed property like so:我可以像这样在计算属性中设置属性:

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
    }
}

But then the compiler gives me a warning: error: Unexpected side effect in "product" computed property但是随后编译器给了我一个警告: error: Unexpected side effect in "product" computed property

Accordingly to OP's comments, his intention is to get and load some initial data. 根据OP的评论,他的意图是获取并加载一些初始数据。 The common way to achieve this behavior is to place it inside created or mounted vuejs lifecycle hooks. 实现此行为的常用方法是将其放在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>

Your structure is a bit all over the place. 您的结构到处都是。 product is a computed, so it runs whenever it's source values change. product是经过计算的,因此只要其源值发生更改,它就会运行。 (You have no control over when it runs.) It shouldn't have side effects (assignments this.description , this.title ), or trigger network requests. (您无法控制它的运行时间。)它不应有副作用(分配this.descriptionthis.title )或触发网络请求。

The code in product is fetching your source data. product的代码正在获取您的源数据。 This belongs in methods , linked explicitly to a user action or a lifecyle event. 这属于methods ,该methods显式链接到用户操作或生命周​​期事件。

Why do you need to copy your data ( this.description = product.description in watch:product )? 为什么你需要复制数据( this.description = product.descriptionwatch:product )? Vue works best when you have your data (your app state) outside Vue, in a global variable say. 如果将数据(您的应用程序状态)置于Vue之外(以全局变量表示),则Vue效果最佳。 Then your Vue components just transparently reflect whatever the app state is at a given moment. 然后,您的Vue组件将透明地反映给定时刻的应用程序状态。

Hope this helps. 希望这可以帮助。

Try the following:请尝试以下操作:

watch: {
    product: {
        immediate: true,
        handler(value) { 
            updateCode();
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM