Vue 通过 watch 选项提供了一个更通用的方法,来响应数据的变化。当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。
<div id="watch-example"> <p> Ask a yes/no question: <input v-model="question"> </p> <p>{{ answer }}</p> </div> ... 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 } }