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

时间:2018-07-21 19:53:27

标签: javascript vue.js vuejs2 vuex

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

2 个答案:

答案 0 :(得分:2)

根据OP的评论,他的意图是获取并加载一些初始数据。 实现此行为的常见方法是将其放置在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>

答案 1 :(得分:0)

您的结构到处都是。 product是经过计算的,因此只要其源值发生更改,它就会运行。 (您无法控制它的运行时间。)它不应有副作用(分配this.descriptionthis.title)或触发网络请求。

product中的代码正在获取您的源数据。它属于methods,并明确链接到用户操作或生命周​​期事件。

您为什么需要复制数据(this.description = product.description中的watch:product)?如果将数据(您的应用程序状态)置于Vue之外(以全局变量表示),则Vue效果最佳。然后,您的Vue组件将透明地反映给定时刻的应用程序状态。

希望这会有所帮助。