计算属性允许声明地计算衍生值,但在有些情况下,则需要在状态变化时执行一些更改,例如更改DOM,或是根据异步操作的结果去修改另一处的状态。

选项式API,使用watch选项在每次响应式属性发生变化时触发一个函数。

export default {
  data() {
    return {
      question: '',
      answer: 'Questions usually contain a question mark. ;-)'
    }
  },
  watch: {
    // 每当 question 改变时,这个函数就会执行
    question(newQuestion, oldQuestion) {
      if (newQuestion.includes('?')) {
        this.getAnswer()
      }
    }
  },
  methods: {
    async getAnswer() {
      this.answer = 'Thinking...'
      try {
        const res = await fetch('https://yesno.wtf/api')
        this.answer = (await res.json()).answer
      } catch (error) {
        this.answer = 'Error! Could not reach the API. ' + error
      }
    }
  }
}

<p>
  Ask a yes/no question:
  <input v-model="question" />
</p>
<p>{{ answer }}</p>

watch选项支持把键设置成用.分隔的路径。

export default {
  watch: {
    // 注意:只能是简单的路径,不支持表达式。
    'some.nested.key'(newValue) {
      // ...
    }
  }
}

深层侦听器

watch默认是浅层的,被侦听的属性仅在被赋新值时,才触发回调函数,而嵌套属性的变化不会触发。

对于嵌套的变更,则需要深层侦听器。

export default {
  watch: {
    someObject: {
      handler(newValue, oldValue) {
        // 注意:在嵌套的变更中,
        // 只要没有替换对象本身,
        // 那么这里的 `newValue` 和 `oldValue` 相同
      },
      deep: true
    }
  }
}

注意:

深层侦听需要遍历被侦听对象中的所有嵌套的属性,当用于大型数据结构时,开销很大,非必要不使用。

即时回调的侦听器

watch默认是懒执行的,仅当数据源变化时,才会执行回调。

当需要在创建侦听器时,立即执行一遍回调,即想请求一些初始数据,然后在相关状态更改时重新请求数据。

可以用一个对象来声明侦听器,这个对象有handler方法和immediate:true选项。

export default {
  // ...
  watch: {
    question: {
      handler(newQuestion) {
        // 在组件实例创建时会立即调用
      },
      // 强制立即执行回调
      immediate: true
    }
  }
  // ...
}

回调的触发时机

  • 更改了响应式状态,可能会同时触发Vue组件更新和侦听器回调

  • 默认情况下,都会在Vue组件更新之前被调用,即在侦听器回调中访问的DOM将是被Vue更新之前的状态

  • 若要在侦听器回调中能访问被Vue更新之后的DOM,需要指明flush: 'post'选项

export default {
  // ...
  watch: {
    key: {
      handler() {},
      flush: 'post'
    }
  }
}

this.$watch()

//组件实例的 $watch() 方法
export default {
  created() {
    this.$watch('question', (newQuestion) => {
      // ...
    })
  }
}
//可以在特定条件下设置一个侦听器,或者只侦听响应用户交互的内容
//允许提前停止该侦听器

停止侦听器

watch 选项或者 $watch() 实例方法声明的侦听器,会在宿主组件卸载时自动停止。

如果需要在组件卸载之前就停止一个侦听器,可以调用$watch()API返回的函数。

const unwatch = this.$watch('foo', callback)

// ...当该侦听器不再需要时
unwatch()
文章作者: Sleny
版权声明: 本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 咸鱼说
Vue Vue
喜欢就支持一下吧
打赏
微信 微信
支付宝 支付宝