Vue中的深度观察入门
在大多数情况下,当与数据打交道时,比如表单,你需要观察数据,并在发生变化时触发一个事件。通常只要我们与数据结构(如数组、对象或字符串)打交道,就可以做到这一点。
然而,在Vue.js或其他任何编程语言中,当我们有嵌套数据时,这种观察器默认是不工作的。嵌套数据使得我们很难跟踪数据结构的变化。
在本教程中,我们将学习如何使用Vue.js来观察嵌套数据结构的变化。然后我们将看看这个功能的详细实现,以实现观察功能。
前提条件
要跟上本教程,读者需要具备以下条件。
- 具有JavaScript的基本知识,尤其是ES2016及以上版本。
- 对Vue.js框架的基本了解。如果你来自另一个库,如React或Angular框架,这些概念可能是相似的。
- 对Docker的了解会有帮助,但不是必须的。
- 在本地安装一个Vue CLI。在本教程中,我们将使用4.15.x版本的CLI。这是写作时的当前版本,在你阅读时可能会发生变化。
- 你选择的一个IDE。在本教程中,我们将使用Visual Studio Code。
目标
在本教程中,我们将学习如何使用Vue.js来观察嵌套数据结构的变化。
什么是观察者?
在最高层面上,我们可以将观察者描述为每当数据发生变化时调用的一个函数。
然而,在某些情况下,我们可能希望在数据的某个特定属性发生变化时得到通知。例如,如果我们有一个像下面这样的数据结构。
{
"name": "John",
"age": 30,
"address": {
"street": "Main Street",
"city": "New York",
"state": "NY"
}
}
在上述数据结构中,我们有一个名为name 的属性,是一个字符串。我们也有一个叫做age 的属性,是一个整数。我们还有一个叫做address 的属性,它是一个对象。
我们可以使用事件监听器change 来检测name 属性的变化。然而,对于street 属性来说,情况就不是这样了。这是因为Vue.js或其他任何编程语言都不知道如何观察嵌套数据结构的变化。
为了克服这一限制,Vue.js为我们提供了一种方法来观察嵌套数据结构中发生的变化,我们将在下一节中看到。
Vue项目设置
Vue.js是一个基于组件的框架。因此,为了使用Vue.js,我们需要创建一个带有一些组件的Vue项目。
让我们运行下面的命令来创建一个新的Vue项目,名为vue-watcher-tutorial 。
vue create vue-watcher-tutorial
上述命令将在当前目录下创建一个名为vue-watcher-tutorial 的新目录。
在本教程中,我们将使用docker来容器化项目。然而,如果你不熟悉docker或者你没有安装docker机器,你可以跳过这一部分。
接下来,我们需要对我们的Vue项目进行dockerize。为了实现这一点,让我们在我们的项目根目录下添加一个Dockerfile 。
这个Dockerfile 将包含以下内容。
# get node version, you even use the LTS
FROM node:16.13.2-alpine
# install a test server to run our project
RUN npm install http-server
# set our work directory to watcher-tutorial
WORKDIR /watcher-tutorial
# copy the package.json. You may as well add the lock file
COPY package.json ./
# if you're planning to add private dependencies in the future, set the scope to the organisation name
RUN npm config set scope <organisation-name> --global
# the .npmrc file will contain the credentials for the npm registry
COPY .npmrc .npmrc
# install the dependencies
RUN npm install --quiet node-gyp -g
# next, remove the .npmrc file
RUN rm -f .npmrc
# copy the files
COPY . .
# Build the vue project
RUN npm run build
# expose the port 8000
EXPOSE 8000
# run the test server
CMD ["http-server", "dist"]
在上面的dockerfile中,我们将FROM 命令设置为使用节点版本16.13.2-alpine ,我们将RUN 命令设置为安装http-server 包。
我们还设置了WORKDIR 命令来设置工作目录为watcher-tutorial 。而COPY 命令将复制package.json 文件到当前目录。
你的.npmrc 文件将包含npm注册表的凭证,如下所示。
//registry.npmjs.org/:_authToken=npm_mexxxxxaSvdxxxGUnR8O9cU2sxxxxxxxxxxx
// 斜线表示该注册表是私有的。在某些情况下,它会将http/https 协议添加到注册表中。
接下来,让我们来构建docker镜像。要做到这一点,我们将运行以下命令。
docker build -t watcher-tutorial .
当构建过程完成后,我们将得到一个新的docker镜像,名为watcher-tutorial 。接下来,我们将运行以下命令来运行该docker镜像。
docker run -p 8000:8000 watcher-tutorial
现在你可以在localhost:8000 上访问你的热加载的Vue项目。
然而,如果你不想使用docker,你可以运行以下命令来运行该项目。
npm run serve
在下一节,我们将学习如何使用Vue.js来观察嵌套数据结构的变化。
快速了解观察者的例子
现在我们有了项目的设置,让我们继续,创建一个新的组件,名为ProductComponent.vue 。
接下来,编辑这个组件,如下。
<template>
</template>
<script>
export default {
name: "ProductComponent",
data(){
return{
quantity: 0,
price: 0,
}
},
watch:{
quantity(newVal, oldVal){
if(newVal < 1){
this.quantity = 1;
}
},
price: function(newVal, oldVal){
if(newVal < 0){
this.price = 0;
}
}
}
}
</script>
<style scoped>
</style>
我们在上面的组件中创建了一个名为ProductComponent.vue 的新组件。然后我们创建了一个名为quantity 的新数据属性,并将其设置为0 。我们还创建了一个名为price 的新数据属性,并将其设置为0 。
接下来,我们创建了一个名为quantity 的新观察属性,并将其设置为一个函数。每当quantity 属性发生变化时,这个函数将被调用。该函数将接收新值和旧值作为参数。
我们还创建了一个名为price 的新监视属性,并将其设置为一个函数。每当price 属性发生变化时,这个函数就会被调用。该函数将接收新值和旧值作为参数。
从上面的实现来看,我们可以很容易地观察我们的数据发生的任何变化,并作出相应的反应。
我们注意到,实现这种行为是非常直接的。然而,当我们把
price和quantity属性作为嵌套的数据结构时会发生什么?
在嵌套的数据结构中实现深度观察
现在我们有了一个关于watch 属性的例子,我们将学习如何在嵌套数据结构中实现深度观察。
让我们开始修改我们之前创建的组件,ProductComponent.vue ,如下所示。
<template>
</template>
<script>
export default {
name: "ProductComponent",
data(){
return{
product: {
name: '',
price: 0,
description: '',
image: '',
quantity: 0
}
}
},
watch:{
quantity(newVal, oldVal){
if(newVal < 1){
this.product.quantity = 1;
}
},
price: function(newVal, oldVal){
if(newVal < 0){
this.product.price = 0;
}
}
}
}
</script>
<style scoped>
</style>
我们已经创建了一个新的数据属性,叫做product ,并将其设置为上述场景中的一个对象。我们还像以前一样添加了观察者。
令人惊讶的是,只要price 或quantity 发生变化,这些函数就不会被执行。product 属性是一个对象,而不是一个原始值。
Vue在watch 属性中为我们提供了deep 选项来克服这个限制。这个选项将允许我们观察嵌套数据结构的变化。
这是通过定义我们的观察者,使其表现为一个应该接收处理函数的对象而实现的。
让我们看一下我们的例子。
<template>
</template>
<script>
export default {
name: "ProductComponent",
data(){
return{
product: {
name: '',
price: 0,
description: '',
image: '',
quantity: 0
}
}
},
watch:{
quantity: {
handler: function (newVal, oldVal) {
if(newVal < 1){
this.product.quantity = 1;
}
},
deep: true
},
price: {
handler: function (newVal, oldVal) {
if(newVal < 1){
this.product.price = 1;
}
},
deep: true
}
}
}
</script>
<style scoped>
</style>
在上面的例子中,我们创建了一个名为product 的新数据属性,并将其设置为一个对象。我们还像以前一样添加了观察者。然后在观察者对象中我们添加了一个处理函数。每当quantity 和price 属性发生变化时,这个函数将被调用。
这就是Vue中深度观察的概念。
它有一个局限性,即它需要遍历我们正在观察的对象中的所有嵌套属性。当涉及到算法效率时,这是一个昂贵的操作。只在必要时使用。
总结
本教程教我们如何使用Vue CLI创建一个Vue.js项目。我们还学习了如何使用watch 属性来实现对嵌套数据结构的深度观察。