vue 侦听器


Vue 通过 watch 选项提供了一个更通用的方法,来响应数据的变化。当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。

"watch-example">

Ask a yes/no question: "question">

{{ answer }}

... var watchExampleVM = new Vue({ el: '#watch-example', data: { question: '', answer: 'I cannot give you an answer until you ask a question!' }, watch: { // 如果 `question` 发生改变,这个函数就会运行 question: function (newQuestion, oldQuestion) { this.answer = 'Waiting for you to stop typing...' this.debouncedGetAnswer() } }, created: function () { // `_.debounce` 是一个通过 Lodash 限制操作频率的函数。 this.debouncedGetAnswer = _.debounce(this.getAnswer, 500) }, methods: { getAnswer: function () { if (this.question.indexOf('?') === -1) { this.answer = 'Questions usually contain a question mark. ;-)' return } this.answer = 'Thinking...' var vm = this axios.get('https://yesno.wtf/api') .then(function (response) { vm.answer = _.capitalize(response.data.answer) }) .catch(function (error) { vm.answer = 'Error! Could not reach the API. ' + error }) } } }) ...

使用 watch 选项允许我们执行异步操作,限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态,这些都是计算属性无法做到的。

watch 方法(1)用来跟踪响应式对象,(2)可以获取到新值与旧值。(3) watch第一次绑定的时候,不会执行监听,只有值发生改变才会执行。如果我们需要在最初绑定值的时候也执行函数,则就需要用到 immediate 属性。

在 vue 中,使用 watch 来响应数据的变化

(1)、基础写法

... 
watch: {
    cityName(newName, oldName) {
       // ...
    }
 }
...

(2)、执行函数

...
watch: {
   cityName: 'nameChange'
   }
 }
...

(3)、监听的数据后面写成对象形式,包含 handler 方法 和 immediate,dedp

        (之前我们写的函数就是在写这个 handler 方法;immediate 表示在 watch 中首次绑定的时候,是否执行 handler,值为 true 则表示在 watch 中声明的时候,就立即执行 handler 方法,值为 false ,则和一般使用 watch 一样,在数据发生变化的时候才执行 handler。当需要监听一个对象的改变时,普通的 watch 方法无法监听到对象内部属性的改变,只有在 data 中的数据变化,此时就需要 deep 属性对对象进行深度监听。比如下面的例子中,deep:true 则可以监听到cityName.name 的变化)

data: {
cityName: {id: 1, name: 'shanghai'}
},
... watch: { cityName: { handler(newName, oldName) {
// ... }, deep: true, immediate: true } } ...

当上述的 cityName 对象的属性值较多,每个属性的变化都会执行handler。如果只需要监听对象中的一个属性值,则可以做以下优化,使用字符串的形式监听对象属性:

watch: {
      'cityName.name': {
            handler(newName, oldName) {
                // ...
             },
             deep: true,
             immediate: true
      }
 }
vue