【面试】Vue中,computed与watch的区别是什么 ?

311 阅读2分钟

0. 什么是“区别”

  • 因为computedwatch功能相似之处太多。比如,我说,我和吴彦祖有什么区别?这类问题会被笑掉大牙--因为我俩除了是男人,啥共同点都没。
  • 只要各自描述他们的不同点,各自都是干什么的就行了。

1. 答题思路

1.1 各自解释

  • computed:计算属性,即通过计算得出来的属性。例如,accodringToA必须根据a的值本身计算出来。
  • watch:侦听,即data中的a属性,再以同名函数形式写到watch中即可。

非要说长相上的区别,那就是computed中出现的函数名一般不应在data中出现,而watch中的函数名必须在data中有对应的。

1.2 代码举例

1.2.1 computed

<!---Vue对应的HTML代码,直接照抄官方示例--->

<div id="example"> 
    <p>Original message: "{{ message }}"</p> 
    <!---下面的reversedMessage是重点--->
    <p>Computed reversed message: "{{ reversedMessage }}"</p>
</div>
var vm = new Vue({ 
    el: '#example', 
    data: { 
        message: 'Hello', 
    }, 
    computed: { 
        // 计算属性的 getter,实质上就是利用了getter思想
        // 可以看到,下方的reversedMessage出现在了模板语法中,却没出现在data对象中
        // 由下可知,计算属性终归是“属性”
        reversedMessage: function () {
            // `this` 指向 vm 实例 return 
            this.message.split('').reverse().join('');
        }, 
    }, 
});

1.2.2 watch

依旧直接照抄官方示例。

<div id="watch-example">
    <p> Ask a yes/no question: <input v-model="question"> </p>
    <p>{{ answer }}</p> 
</div>
// 下面的es6+语法是我自己加的
import '_' from 'lodash'; // 鲁大师还是香啊
import 'axios' from 'axios';

var watchExampleVM = new Vue({ 
    el: '#watch-example',
    data: { 
        question: '', 
        answer: 'I cannot give you an answer until you ask a question!', 
    }, 
    watch: {   // 如果 `question` 发生改变,这个函数就会运行 
        // 从长相看,watch中出现的对象必定会在data中出现。这一点很重要
        // 从功能上看,只要question变化,就必须会调用debounceGetAnswer()方法
        question: function (newQuestion, oldQuestion) { 
            this.answer = 'Waiting for you to stop typing...' ;
            this.debouncedGetAnswer(); 
        }
    }, 
    created: function () {  
        // `_.debounce` 是一个通过 Lodash 限制操作频率的函数。   
        // 在这个例子中,我们希望限制访问 yesno.wtf/api 的频率   
        // AJAX 请求直到用户输入完毕才会发出。想要了解更多关于 
        // `_.debounce` 函数 (及其近亲 `_.throttle`) 的知识, 
        // 请参考:https://lodash.com/docs#debounce 
        this.debouncedGetAnswer = _.debounce(this.getAnswer, 500); 
    }, 
    methods: { 
        getAnswer: function () { 
            if (this.question.indexOf('?') === -1) { 
                this.answer = 'Questions usually contain a question mark. ;-)' ;
                return ;
            } 
            this.answer = 'Thinking...';
            var vm = this; 
            axios.get('https://yesno.wtf/api')
                .then(function (response) { 
                    vm.answer = _.capitalize(response.data.answer); 
                }) .catch(function (error) { 
                vm.answer = 'Error! Could not reach the API. ' + error; 
            }); 
        } 
    } 
});

1.3 watch额外还有两个属性

  • deep:类型为Boolean,表示是否监听对象内部值的变化。用于data中包含了Object的情况。默认值false
  • immediate:类型为Boolean,表示是否以计算属性的当前值触发回调。

1.4 watch的特点

watch支持异步操作而computed不支持。