首页 > 编程笔记

Vue watch(监听器)详解

在 Vue.js 中,当需要在数据发生变化且需要执行异步代码或开销比较大的逻辑时,使用 compute 属性不合适,开发者可以自定义一个 watch 监听器,来监听数据的变化。

举个简单的例子:
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>test Vue.js</title>
    <script src="https://cdn.jsdelivr.net/npm/lodash@4.13.1/lodash.min.js"></script>
    <script type="text/javascript" src="../static/js/Vue.js"></script>
</head>

<body>
    <div id="app">
        <p>
            输入问题:
            <input v-model="question">
        </p>
        <p>{{ answer }}</p>
    </div>

    <script>
        const vm = new Vue({
            el: "#app",
            data: {
                question: '',
                answer: '输入问题,我才好给你答案'
            },
            watch: {
                // 监听question的变化,自动调用
                question: function () {
                    this.answer = '等待你输入问题';
                    this.debouncedGetAnswer();
                }
            },
            created: function () {
                // 500ms后调用getAnswer方法,控制调用频率
                this.debouncedGetAnswer = _.debounce(this.getAnswer, 500);
            },
            methods: {
                getAnswer: function () {
                    this.answer = "思索中…";
                    window.setTimeout(getResult, 500);
                }
            }
        });

        function getResult() {
            console.log("1111");
            vm.$data.answer = "答案是:" + (1 + Math.random());
        }
    </script>
</body>

</html>
在上面的代码中,定义了一个 question 监听器,用于监听 question 数据属性。当 question 数据属性发生变化时,会自动执行 question 监听器后面的函数内容。在 question 监听器的函数逻辑中执行的是一个异步延时代码。

计算属性和watch监听器的对比

watch 监听器是 Vue.js 提供的一种用来观察和响应 Vue.js 实例上的数据变动的一种方式,一般只用于变动的开销比较大或异步方法调用的情况。否则使用计算属性要比使用 watch 监听器合适。

虽然可以用 watch 监听器监听 firstName1 和 lastName1 的变化,但是用计算属性计算 fullName2 要简单得多,代码如下:
<div id="app">
    FirstName1 <input type="text" v-model="firstName1"> LastName1 <input type="text" v-model="lastName1"><br/>
    FullName1 {{ fullName1 }}<br/><br/>
    FirstName2 <input type="text" v-model="firstName2"> LastName2 <input type="text" v-model="lastName2"><br/>
    FullName2 {{ fullName2 }}<br/><br/>
</div>

<script type="text/javascript">

    const vm = new Vue({
        el: '#app',
        data: {
            firstName1: '',
            lastName1: '',
            fullName1: '', // This will be updated via watch
            firstName2: '',
            lastName2: ''
        },
        watch: {
            firstName1: function() {
                this.fullName1 = this.firstName1 + ' ' + this.lastName1;
            },
            lastName1: function() {
                this.fullName1 = this.firstName1 + ' ' + this.lastName1;
            }
        },
        computed: {
            fullName2: function() {
                return this.firstName2 + ' ' + this.lastName2;
            }
        }
    });

</script>

推荐阅读