• 首页
  • css3教程
  • html5教程
  • jQuery手册
  • vue手册
  • php手册
  • MySQL手册
  • apache手册
  • redis手册
  • $watch

    • 参数:
      • {string | Function}source
      • {Function | Object}callback
      • {Object}[options]
        • {boolean}deep
        • {boolean}immediate
        • {string}flush
    • 返回:{Function}unwatch
    • 用法:侦听组件实例上的响应式 property 或函数计算结果的变化。回调函数得到的参数为新值和旧值。我们只能将顶层的datapropcomputed property 名作为字符串传递。对于更复杂的表达式,用一个函数取代。


    const app = Vue.createApp({
      data() {
        return {
          a: 1,
          b: 2,
          c: {
            d: 3,
            e: 4
          }
        }
      },
      created() {
        // 顶层property 名
        this.$watch('a', (newVal, oldVal) => {
          // 做点什么
        })
    
        // 用于监视单个嵌套property 的函数
        this.$watch(
          () => this.c.d,
          (newVal, oldVal) => {
            // 做点什么
          }
        )
    
        // 用于监视复杂表达式的函数
        this.$watch(
          // 表达式 `this.a + this.b` 每次得出一个不同的结果时
          // 处理函数都会被调用。
          // 这就像监听一个未被定义的计算属性
          () => this.a + this.b,
          (newVal, oldVal) => {
            // 做点什么
          }
        )
      }
    })
    

    当侦听的值是一个对象或者数组时,对其属性或元素的任何更改都不会触发侦听器,因为它们引用相同的对象/数组:

    const app = Vue.createApp({
      data() {
        return {
          article: {
            text: 'Vue is awesome!'
          },
          comments: ['Indeed!', 'I agree']
        }
      },
      created() {
        this.$watch('article', () => {
          console.log('Article changed!')
        })
    
        this.$watch('comments', () => {
          console.log('Comments changed!')
        })
      },
      methods: {
        // 这些方法不会触发侦听器,因为我们只更改了Object/Array的一个property,
        // 不是对象/数组本身
        changeArticleText() {
          this.article.text = 'Vue 3 is awesome'
        },
        addComment() {
          this.comments.push('New comment')
        },
    
        // 这些方法将触发侦听器,因为我们完全替换了对象/数组
        changeWholeArticle() {
          this.article = { text: 'Vue 3 is awesome' }
        },
        clearComments() {
          this.comments = []
        }
      }
    })
    

    $watch返回一个取消侦听函数,用来停止触发回调:

    const app = Vue.createApp({
      data() {
        return {
          a: 1
        }
      }
    })
    
    const vm = app.mount('#app')
    
    const unwatch = vm.$watch('a', cb)
    // later, teardown the watcher
    unwatch()
    


    选项:deep

    为了发现对象内部值的变化,可以在选项参数中指定deep: true。注意监听数组的变更不需要这么做。

    vm.$watch('someObject', callback, {
    	deep: true
    })
    vm.someObject.nestedValue = 123
    // callback is fired
    


    选项:immediate

    在选项参数中指定immediate: true将立即以表达式的当前值触发回调:

    vm.$watch('a', callback, {
    	immediate: true
    })
    // 立即以 `a` 的当前值触发 `callback`
    

    注意,在带有immediate选项时,你不能在第一次回调时取消侦听给定的 property。

    // 这会导致报错
    const unwatch = vm.$watch(
      'value',
      function() {
        doSomething()
        unwatch()
      },
      { immediate: true }
    )
    

    如果你仍然希望在回调内部调用一个取消侦听的函数,你应该先检查其函数的可用性:

    let unwatch = null
    
    unwatch = vm.$watch(
      'value',
      function() {
        doSomething()
        if (unwatch) {
          unwatch()
        }
      },
      { immediate: true }
    )
    


    选项: flush

    flush选项允许更好地控制回调的时间。它可以设置为prepostsync

    • pre,默认值,指定在呈现前应调用回调。这允许回调在模板运行之前更新其他值。
    • post,可用于将回调推迟到呈现之后。如果回调需要通过$refs访问更新的DOM或子组件,则应使用此选项。
    • sync,则一旦值发生更改,将同步调用回调。

    对于prepost,回调将使用队列进行缓冲。回调只会添加到队列一次,即使监视的值更改了多次。临时值将被跳过,不会传递给回调。缓冲回调不仅提高了性能,而且有助于确保数据一致性。在执行数据更新的代码完成之前,不会触发观察程序。sync应谨慎使用观察程序,因为它们没有这些好处。

    上篇:$el

    下篇:$emit