美文网首页Vuevue之watch侦听器
[vue3进阶] 1.侦听器watch的进阶用法

[vue3进阶] 1.侦听器watch的进阶用法

作者: 林哥学前端 | 来源:发表于2021-09-26 08:45 被阅读0次

我们之前学习过侦听器watch,它用来侦听数据变化,让我们可以在数据变化以后,做一些操作,比如向后台请求数据等。这节课我们继续学习关于watch的更多内容。

1.deep属性

如果使用watch监听一个对象或者数组,当对象和数组里面的数据发生变化时,是不会触发监听器的,
我们来看下面这个例子

<template>
  <div>
    <ul>
      <li v-for="item in list" :key="item">
        {{ item }}
      </li>
    </ul>
    <div>{{ person.name }}的年龄是{{ person.age }}岁</div>
  </div>
</template>

<script>
// watch进阶
export default {
  name: 'App',
  data() {
    return {
      list: ['苏格拉底', '柏拉图', '亚里士多德'],
      person: {
        name: '苏格拉底',
        age: 18,
      },
    }
  },
  watch: {
    list(newVal, oldVal) {
      console.log('list数组改变了')
      console.log('改变以后的值' + newVal)
      console.log('改变以前的值' + oldVal)
    },
    person(newVal, oldVal) {
      console.log('person的数据变化了')
      console.log('改变以后的值' + newVal)
      console.log('改变以前的值' + oldVal)
    },
  },
  mounted() {
    // 在组件挂载以后,改变对象和数组里面的数据
    this.list.push('亚历山大')
    this.person.age = 19
  },
}
</script>

<style></style>

运行以后发现,控制台什么都没有打印,说明侦听器确实也没有触发,
但是实际开发中难免有这种需求,需要数组和对象变化时处理一些逻辑
这是就需要deep出场了
deep我们知道是深的意思,这里就是我们要深度侦听这个对象,它里面发生了变化也要触发侦听
现在就需要改变一下watch的写法了,

  watch: {
    list: {
      deep: true,
      handler: function(newVal, oldVal) {
        console.log('list数组改变了')
        console.log('改变以后的值' + newVal)
        console.log('改变以前的值' + oldVal)
      },
    },
    person: {
      deep: true,
      handler: function(newVal, oldVal) {
        console.log('person的数据变化了')
        console.log('改变以后的年龄' + newVal.age)
        console.log('改变以前的年龄' + oldVal.age)
      },
    },
  },

需要被监听的数据作为一个键,它的值是一个对象,对象里添加了一个deep属性,值是true,说明要对这个数据进行深度侦听,handler就是我们之前写的数据发生变化以后的回调函数
这里需要注意,handler这个函数必须使用function,而不能使用箭头函数,因为vue要指定这个函数里面的this指针指向我们当前这个vue组件
现在运行代码,发现控制台输出了



说明侦听器确实触发了,但是有个问题,newVal和值和oldVal的值是一样的,因为对象和数组的引用地址并没有变,所以它们是一样的,这里需要注意一下。

先来小总结一下,有3点需要注意
1)侦听器从函数方式改成了对象方式
2)handler的回调函数必须使用function的方式定义
3)对象和数组改变时,新值和旧值是相同的

如果确实需要得到对象里面数据变化前后的值,可以用这种方式

 watch: {
    'person.age': {
      handler: function(newVal, oldVal) {
        console.log('person的数据变化了')
        console.log('改变以后的年龄' + newVal)
        console.log('改变以前的年龄' + oldVal)
      },
    },
  },

这里侦听的键变成了一个字符串,表示要专门侦听person的age属性,这时不用deep也可以侦听到变化了,同时可以获取新值和旧值


2.immediate

immediate本来就是‘立即’的意思,我们可以给要watch对象增加immediate:true,表示在页面初始化时,就调用侦听的回调函数

    'person.age': {
      handler: function(newVal, oldVal) {
        console.log('person的数据变化了')
        console.log('改变以后的年龄' + newVal)
        console.log('改变以前的年龄' + oldVal)
      },
      immediate: true,

同时新增了生命周期函数的打印,来表明侦听执行的时机

  beforeCreate() {
    console.log('创建之前')
  },
  created() {
    console.log('创建完成')
  },

结果是



在beforeCreate之后,created之前执行了回调函数,
这里我们发现改变之前的值是undefined,因为这个值之前还没有定义
这就是immediate的用法

3.flush

flush选项表示回调函数调用的时机,有三个值可以选择
pre:默认值,表示在dom更新前调用,比如这是你需要再改变其他数据,就使用pre,这些数据改变完一起更新dom,提高性能
post:表示dom更新完成后调用,比如你要获取dom或者子组件,跟我们之前使用nextTick的意思一样
sync:同步调用,官网表示不要用这个

4.$watch用法

除了我们定义watch对象的方式添加侦听,也可以是用this.$watch方法

  created() {
    console.log('创建完成')
    this.$watch(
      'person.age',
      (newVal, oldVal) => {
        console.log('person的数据变化了')
        console.log('改变以后的年龄' + newVal)
        console.log('改变以前的年龄' + oldVal)
      },
      {
        immediate: true,
      }
    )
  },

这时候就可以用箭头函数了

$watch的语法就是这样了,接受三个参数

 this.$watch(
     要侦听的数据,
     回调函数,
     选项
    )
  },

同时$watch方法返回一个方法,用于去掉监听

  created() {
    console.log('创建完成')
    const unwatch = this.$watch('person.age', (newVal, oldVal) => {
      console.log('person的数据变化了')
      console.log('改变以后的年龄' + newVal)
      console.log('改变以前的年龄' + oldVal)
    })

    unwatch()
  },

关于watch的所有用法基本都介绍完了,大家可以动手写一写,体会一下。

相关文章

网友评论

    本文标题:[vue3进阶] 1.侦听器watch的进阶用法

    本文链接:https://www.haomeiwen.com/subject/msbwgltx.html