做自(zì)由與創造的先行者

偵聽器

Vue.js中文(wén)手冊

基本示例 ​

計(jì)算(suàn)屬性允許我們聲明(míng)性地計(jì)算(suàn)衍生值。然而在有些(xiē)情況下(xià),我們需要在狀态變化時(shí)執行一些(xiē)“副作(zuò)用(yòng)”:例如更改 DOM,或是根據異步操作(zuò)的結果去修改另一處的狀态。

在選項式 API 中,我們可以使用(yòng) watch 選項在每次響應式屬性發生變化時(shí)觸發一個函數。

js

export default {

data() {

return {

question: '',

answer: 'Questions usually contain a question mark. ;-)'

}

},

watch: {

// 每當 question 改變時(shí),這(zhè)個函數就會(huì)執行

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

}

}

}

}

template

<p>

Ask a yes/no question:

<input v-model="question" />

</p>

<p>{{ answer }}</p>

watch 選項也(yě)支持把鍵設置成用(yòng) . 分隔的路徑:

js

export default {

watch: {

// 注意:隻能(néng)是簡單的路徑,不支持表達式。

'some.nested.key'(newValue) {

// ...

}

}

}

深層偵聽器 ​

watch 默認是淺層的:被偵聽的屬性,僅在被賦新值時(shí),才會(huì)觸發回調函數——而嵌套屬性的變化不會(huì)觸發。如果想偵聽所有嵌套的變更,你(nǐ)需要深層偵聽器:

js

export default {

watch: {

someObject: {

handler(newValue, oldValue) {

// 注意:在嵌套的變更中,

// 隻要沒有替換對(duì)象本身,

// 那麽這(zhè)裏的 `newValue` 和(hé) `oldValue` 相同

},

deep: true

}

}

}

謹慎使用(yòng)

深度偵聽需要遍曆被偵聽對(duì)象中的所有嵌套的屬性,當用(yòng)于大(dà)型數據結構時(shí),開(kāi)銷很(hěn)大(dà)。因此請(qǐng)隻在必要時(shí)才使用(yòng)它,并且要留意性能(néng)。

即時(shí)回調的偵聽器 ​

watch 默認是懶執行的:僅當數據源變化時(shí),才會(huì)執行回調。但(dàn)在某些(xiē)場景中,我們希望在創建偵聽器時(shí),立即執行一遍回調。舉例來(lái)說,我們想請(qǐng)求一些(xiē)初始數據,然後在相關狀态更改時(shí)重新請(qǐng)求數據。

我們可以用(yòng)一個對(duì)象來(lái)聲明(míng)偵聽器,這(zhè)個對(duì)象有 handler 方法和(hé) immediate: true 選項,這(zhè)樣便能(néng)強制回調函數立即執行:

js

export default {

// ...

watch: {

question: {

handler(newQuestion) {

// 在組件實例創建時(shí)會(huì)立即調用(yòng)

},

// 強制立即執行回調

immediate: true

}

}

// ...

}

回調函數的初次執行就發生在 created 鈎子之前。Vue 此時(shí)已經處理(lǐ)了(le) data、computed 和(hé) methods 選項,所以這(zhè)些(xiē)屬性在第一次調用(yòng)時(shí)就是可用(yòng)的。

回調的觸發時(shí)機 ​

當你(nǐ)更改了(le)響應式狀态,它可能(néng)會(huì)同時(shí)觸發 Vue 組件更新和(hé)偵聽器回調。

默認情況下(xià),用(yòng)戶創建的偵聽器回調,都會(huì)在 Vue 組件更新之前被調用(yòng)。這(zhè)意味着你(nǐ)在偵聽器回調中訪問的 DOM 将是被 Vue 更新之前的狀态。

如果想在偵聽器回調中能(néng)訪問被 Vue 更新之後的 DOM,你(nǐ)需要指明(míng) flush: 'post' 選項:

js

export default {

// ...

watch: {

key: {

handler() {},

flush: 'post'

}

}

}

this.$watch() ​

我們也(yě)可以使用(yòng)組件實例的 $watch() 方法來(lái)命令式地創建一個偵聽器:

js

export default {

created() {

this.$watch('question', (newQuestion) => {

// ...

})

}

}

如果要在特定條件下(xià)設置一個偵聽器,或者隻偵聽響應用(yòng)戶交互的内容,這(zhè)方法很(hěn)有用(yòng)。它還允許你(nǐ)提前停止該偵聽器。

停止偵聽器 ​

用(yòng) watch 選項或者 $watch() 實例方法聲明(míng)的偵聽器,會(huì)在宿主組件卸載時(shí)自(zì)動停止。因此,在大(dà)多數場景下(xià),你(nǐ)無需關心怎麽停止它。

在少數情況下(xià),你(nǐ)的确需要在組件卸載之前就停止一個偵聽器,這(zhè)時(shí)可以調用(yòng) $watch() API 返回的函數:

js

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

// ...當該偵聽器不再需要時(shí)

unwatch()

網站(zhàn)建設開(kāi)發|APP設計(jì)開(kāi)發|小(xiǎo)程序建設開(kāi)發
下(xià)一篇:模闆引用(yòng)
上(shàng)一篇:生命周期鈎子