美文网首页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