Vue $watch() 方法


示例

使用 $watch() 方法创建一个观察程序,每次"value"数据属性更改时都会写入一条新消息。

mounted() {
  this.$watch('value', function() {
    this.results.push('$watch() method')
  })
}
运行示例 »

请参阅下面的更多示例。


定义和用法

$watch() 方法用于创建观察者。

$watch() 方法返回一个停止函数,我们可以用它来停止观察者。 (参见示例 4

观察者被设置为观察值的变化(第一个参数),并在变化发生时执行某些操作(第二个参数)。 还可以为观察者定义其他属性(第三个参数)。

参数 描述
watch source 必填。 第一个参数是监视源。 这可以是组件属性名称字符串(上面的示例)、简单的点分隔路径字符串(示例 5) ,或函数(示例 6)。
callback function 必填。 第二个参数是一个回调函数,当监视源发生更改时运行。 可以将回调函数设置为接收监视源的新值和旧值作为参数(参见示例 1)。
options object 可选。 这里我们可以指定选项 deep(深度)、immediate、flush 和 onTrigger/onTrack。

deep: 默认值为 'false'。 如果观察者为 deep,它也会对观察者设置要观察的属性中更深处的变化做出反应。 (参见示例 2

immediate: 默认值为 'false'。 创建后立即触发观察者。 当"immediate"设置为"true"时,第一次触发观察者时,旧值将是"undefined"。 (参见示例 3

flush: 默认值是 'pre'。 指定相对于组件渲染时间运行回调函数的时间。 可能的值为"pre"、"post"和"sync"。 请谨慎使用此冲洗选项。

onTrigger/onTrack: 用于调试。 仅适用于开发模式。

注意:还可以使用watch选项创建观察者。


更多示例

示例 1

每次"value"数据属性发生变化时,使用 $watch() 方法用旧值和新值写入新消息。

<template>
  <h2>示例 $watch() 方法</h2>
  <p>拖动滑块改变值,从而触发 $watch() 方法。 回调函数使用新值和旧值写入一条消息。</p>
  <div>
    <p><input type="range" min="0" max="10" v-model="value"> Current value: {{ value }}</p>
    <ol>
      <li v-for="x in results">{{ x }}</li>
    </ol>
  </div>
</template>

<script>
export default {
  data() {
    return {
      value: 4,
      results: []
    };
  },
  mounted() {
    this.$watch('value', function(newVal, oldVal) {
      this.results.push('Old value:'+oldVal+', new value: '+newVal)
    })
  }
};
</script>

<style scoped>
div {
  border: solid black 1px;
  padding: 10px;
}
</style>
运行示例 »

示例 2

使用 $watch() 方法,并将 deep 监视选项设置为'true'。 观察者现在可以进一步检测'value'对象内部的变化。

<template>
  <h2>示例 $watch() 方法</h2>
  <p>为斯图尔特登记一项额外的爱好。 爱好存储在'value'对象内的数组中。 $watch() 方法被触发,因为 'deep' 选项设置为 'true',以便观察器还可以检测对象内部的进一步更改。</p>
  <div>
    <p>为斯图尔特注册一个额外的爱好:</p>
    <p><input type="text" ref="inpText"></p>
    <button v-on:click="regHobby">Register</button>
    <ol>
      <li v-for="x in watchMessages">{{ x }}</li>
    </ol>
  </div>
  <p>Current 'value' object:</p>
  <pre>{{ this.value }}</pre>
</template>

<script>
export default {
  data() {
    return {
      value: {
        owner: 'Stuart',
        address: 'Faraway Lane',
        hobbies: ['Bird watching', 'Trail running']
      },
      watchMessages: []
    };
  },
  methods: {
    regHobby() {
      this.value.hobbies.push(this.$refs.inpText.value);
      this.$refs.inpText.value = null;
      this.$refs.inpText.focus();
    }
  },
  mounted() {
    this.$watch('value', function () {
      this.watchMessages.push('watcher triggered')
    }, {
      deep: true
    });
  }
};
</script>

<style scoped>
div {
  border: solid black 1px;
  padding: 10px;
}

li {
  background-color: lightgreen;
}</style>
运行示例 »

示例 3

使用 $watch() 方法,并将 immediate 监视选项设置为"true"。 现在,观察者也会在创建后立即触发。

<template>
  <h2>示例 $watch() 方法</h2>
  <p>将"immediate"选项设置为"true"后,观察者也会在创建后立即触发。</p>
  <div>
    <input type="range" min="0" max="10" v-model="value"> Current value: {{ value }}
    <p>Messages from the watcher:</p>
    <ol>
      <li v-for="x in watchMessages">{{ x }}</li>
    </ol>
  </div>
</template>

<script>
export default {
  data() {
    return {
      value: 4,
      watchMessages: []
    };
  },
  mounted() {
    this.$watch('value', (newVal, oldVal) => {
      this.watchMessages.push('Old value: '+oldVal+' New value: '+newVal)
    }, {
      immediate: true
    });
  }
};
</script>

<style scoped>
div {
  border: solid black 1px;
  padding: 10px;
}

li:first-child {
  background-color: lightgreen;
}</style>
运行示例 »

示例 4

使用 $watch() 方法返回的停止函数来停止观察器。

<template>
  <h2>示例 $watch() 方法</h2>
  <p>拖动滑块以查看观察器的工作情况,单击停止按钮,然后再次拖动滑块以确认观察器现已停止。</p>
  <div>
    <p><input type="range" min="0" max="10" v-model="value"> Current value: {{ value }}</p>
    <button v-on:click="stopFunc">Stop Watcher</button>
    <ol>
      <li v-for="x in results">{{ x }}</li>
    </ol>
  </div>
</template>

<script>
export default {
  data() {
    return {
      value: 4,
      results: [],
      stopFunc: null
    };
  },
  mounted() {
    this.stopFunc = this.$watch('value', function() {
      this.results.push('$watch() method')
    })
  }
};
</script>

<style scoped>
div {
  border: solid black 1px;
  padding: 10px;
}
</style>
运行示例 »

示例 5

使用点分隔的路径字符串,以便 $watch() 方法可以侦听"value"对象内的"country"属性。

<template>
  <h2>示例 $watch() 方法</h2>
  <p>观察程序设置为监视'value.country',因此将检测'value'对象内的国家/地区何时发生更改。</p>
  <div>
    <p>为 Stuart 注册一个新的居住国家/地区:</p>
    <p><input type="text" v-model="inpVal"></p>
    <button v-on:click="regHobby">Register</button>
    <ol>
      <li v-for="x in watchMessages">{{ x }}</li>
    </ol>
  </div>
  <p>Current 'value' object:</p>
  <pre>{{ this.value }}</pre>
</template>

<script>
export default {
  data() {
    return {
      inpVal: null,
      value: {
        owner: 'Stuart',
        address: 'Faraway Lane',
        country: 'Mexico'
      },
      watchMessages: []
    };
  },
  methods: {
    regHobby() {
      this.value.country = this.inpVal;
      this.inpVal = null;
    }
  },
  mounted() {
    this.$watch('value.country', function () {
      this.watchMessages.push('watcher triggered')
    });
  }
};
</script>

<style scoped>
div {
  border: solid black 1px;
  padding: 10px;
}
</style>
运行示例 »

示例 6

使用 $watch() 方法中的函数来监听多个值的变化。

<template>
  <h2>示例 $watch() 方法</h2>
  <p>使用函数作为观察器中的第一个参数来观察值 A 和值 B 之和的变化。</p>
  <div>
    <p>Register a new country for Stuart to live in:</p>
    <p>Value A: <input type="range" min="-10" max="20" v-model="inpValA"> {{ inpValA }}</p>
    <p>Value B: <input type="range" min="-10" max="20" v-model="inpValB"> {{ inpValB }}</p>
    <ol>
      <li v-for="x in watchMessages">{{ x }}</li>
    </ol>
  </div>
</template>

<script>
export default {
  data() {
    return {
      inpValA: 2,
      inpValB: 4,
      watchMessages: []
    };
  },
  mounted() {
    this.$watch( 
      ()=> Number(this.inpValA) + Number(this.inpValB), 
      function (newVal,oldVal) {
        this.watchMessages.push('watcher triggered. A + B = ' + newVal)
      }
    );
  }
};
</script>

<style scoped>
div {
  border: solid black 1px;
  padding: 10px;
}
li {
  background-color: lightgreen;
}
</style>
运行示例 »

相关页面

Vue 教程:Vue 观察者

Vue 教程:Vue 方法

Vue 教程:Vue v-on 指令

Vue 教程:Vue 模板参考

Vue 参考:Vue $refs 对象

JavaScript 教程:JS 箭头函数