如何在 Vue 中使用观察者

在任何 Web 应用程序中,输入数据会改变页面是很正常的。例如,用户可以更新他们的用户名,或提交帖子。在 vue中,我们可以使用watchers来观察这些变化。观察者允许我们检查特定的数据元素或道具,并查看它是否以任何方式被更改。

如果您是 Vue 的新手,请先在此处开始阅读我们制作您的第一个 Vue 应用程序的指南,然后再深入了解观察者。

在 Vue 中使用观察者#

当我们在 Vue 中创建新组件时,也就是一个.vue文件,我们可以通过使用watch. 例如,下面的代码将观察数据元素的变化pageData,并根据它改变的值运行一个函数。

export default {
    name: "MyComponent",
    data() {
        return {
            pageData: [{
                name : "Some Page",
                page : "/article/some-page"
            }]
        }
    },
    watch: {
        pageData: function(value) {
            // If "pageData" ever changes, then we will console log its new value.
            console.log(value);
        }
    }
}

观察 vue 中的 prop 变化

同样,我们可以使用相同的方法观察道具的变化。下面的示例监视名为“”的道具的变化name

export default {
    name: "MyComponent",
    props: {
        name: String
    },
    watch: {
        name: function(value) {
            // Whenever the prop "name" changes, then we will console log its value.
            console.log(value);
        }
    }
}

使用 Vue Watch 获取旧值#

如果我们想检索旧值,即dataorprop在更改之前的值,我们可以使用 watch 函数中的第二个参数来检索它。例如,下面的代码现在将控制台记录 的新值pageData和旧值:

export default {
    name: "MyComponent",
    data() {
        return {
            pageData: [{
                name : "Some Page",
                page : "/article/some-page"
            }]
        }
    },
    watch: {
        pageData: function(newValue, oldValue) {
            // If "pageData" ever changes, then we will console log its new value.
            console.log(newValue, oldValue);
        }
    }
}

组件中的观察者#

现在我们已经了解了观察者是如何工作的——让我们看一个现实生活中的例子。下面的组件有一个计数器,当单击它时,会增加一个名为 的数据值的值totalCount。我们观察 totalCount 的变化,并给定它的值,我们将在页面上显示它。

<template>
    <button @click="totalCount = totalCount + 1">Click me</button>
    <p>{{ message }}</p>
</template>

<script>
export default { 
    name: "Counter",
    data() {
        return {
            // "message" will show up in the template above in 
            message: "You haven't clicked yet!",
            // This is the total number of times the button has been clicked
            totalCount: 0
        }
    },
    watch: {
        // Watch totalCount for any changes
        totalCount: function(newValue) {
            // Depending on the value of totalCount, we will display custom messages to the user
            if(newValue <= 10) {
                this.message = `You have only clicked ${newValue} times.`;
            }
            else if(newValue <= 20) {
                this.message = `Wow, you've clicked ${newValue} times!`;
            }
            else {
                this.message = `Stop clicking, you've already clicked ${newValue} times!`;
            }
        }
    }
}
</script>

观察 Vue 中的深层或嵌套数据变化#

Vue 只在第一层观察对象或数组中的数据变化。因此,如果您期望在较低级别发生变化,比方说pageData[0].name,我们需要做一些稍微不同的事情。这称为深度观察,因为我们观察的是嵌套或深层数据结构,而不仅仅是浅层变化。

因此,深度观察者是一种检查对象本身数据变化的方法。它们遵循相同的结构,除了我们添加deep: true到我们的观察者。例如,下面的代码将记录对象的nameurl属性的变化pageData

export default {
    name: "MyComponent",
    data: {
        return {
            pageData: [{
                name: "My Page",
                url: "/articles/my-page"
            }]
        }
    },
    watch: {
        pageData: {
            deep: true,
            handler: function(newValue, oldValue) {
                // If name or page updates, then we will be able to see it in our
                // newValue variable
                console.log(newValue, oldValue)
            }
        }
    }
}

组件之外的观察者#

如果您想在组件之外使用观察者,您仍然可以使用该watcher()函数来执行此操作。下面显示了一个示例,我们在其中观察对象totalCount外部名为 的变量的变化watch: {}

深度观察者

注意:深度观察者很棒,但对于非常大的对象,它们可能会很昂贵。如果您正在观察一个非常大的对象中的突变,则可能会导致一些性能问题。

ref()因为我们在Vue中包装了 totalCount 的值,所以它是响应式的。这意味着我们可以将它与我们的观察者一起使用。

<script setup>
import { ref, watch } from 'vue'
    
let totalCount = ref(0)

watch(totalCount, function(newValue, oldValue) {
    console.log(newValue, oldValue);
})

通过在末尾添加deep: true选项,您也可以轻松地将它们变成 deep watchers :

watch(totalCount, function(newValue, oldValue) {
    // Similar to before, only it will watch the changes at a deeper level
    console.log(newValue, oldValue);
}, { deep: true });

这意味着您仍然可以利用观察者的价值,而无需将它们包含在export default.

Vue Watch Getter 函数

使用这种格式,我们可以将第一个参数设置watch为函数,并用它来计算一些东西。之后,计算的值就会被监视。例如,下面的代码将两者相加,xy观察其变化。

<script setup>
import { ref, watch } from 'vue'
    
let x = ref(0);
let y = ref(0);
watch(() => x + y, function(newValue, oldValue) {
    console.log(newValue, oldValue);
})

观看效果#

watchEffect是 Vue 3 的一个全新添加,它监视其中任何响应式引用的变化。如前所述,我们可以使用该ref()函数将变量标记为反应式。因此,当我们使用 watchEffect 时,我们不会显式引用特定的值或变量来监视 – 它只是监视其中提到的任何反应变量。这是一个例子:

import { ref, watch } from 'vue'
        
let x = ref(0);
let y = ref(0);

watchEffect(() => {
    console.log(x.value, y.value);
});

++x.value; 
++y.value; // Logs (x, y);

需要注意的事项watchEffect

  • 它将在开始时运行一次– 无需对您的反应数据进行任何更改。这意味着,上面的示例将0, 0在您打开页面时进行控制台日志。
  • 对于深度引用更改,使用watch– watchEffect 如果它进行深度检查将非常低效,因为它必须多次迭代许多不同的变量。

何时使用观察者#

观察者有很多应用,但关键的是:

  • API 请求 – 从服务器请求数据,然后通过观察者观察响应。
  • Websocket 请求 – 监视从 websocket 收集的数据结构的变化。
  • 数据更改需要逻辑 – 等待数据更改,然后使用该值根据观察程序函数中的逻辑更改应用程序。
  • 在不同的数据之间移动时——因为我们既有新的值又有旧的值,我们可以使用观察者来动画我们应用程序中的变化。

结论#

Watchers 是 Vue 3 开发的重要组成部分。有了 watchers,我们可以用最少的代码实现数据的反应性。因此,弄清楚何时以及为什么使用它们是开发任何 Vue 应用程序的重要部分。你可以在这里找到更多我们的Vue 内容