做(zuò)自(zì)由與創造的先行(xíng)者

偵聽器

Vue.js中文手冊

基本示例 ​

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

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

js

export default {

data() {

return {

question: '',

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

}

},

watch: {

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

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 選項也支持把鍵設置成用 . 分隔的路徑:

js

export default {

watch: {

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

'some.nested.key'(newValue) {

// ...

}

}

}

深層偵聽器 ​

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

js

export default {

watch: {

someObject: {

handler(newValue, oldValue) {

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

// 隻要(yào)沒有替換對象本身,

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

},

deep: true

}

}

}

謹慎使用

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

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

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

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

js

export default {

// ...

watch: {

question: {

handler(newQuestion) {

// 在組件實例創建時(shí)會立即調用

},

// 強制立即執行(xíng)回調

immediate: true

}

}

// ...

}

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

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

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

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

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

js

export default {

// ...

watch: {

key: {

handler() {},

flush: 'post'

}

}

}

this.$watch() ​

我們也可(kě)以使用組件實例的 $watch() 方法來命令式地(dì)創建一(yī)個偵聽器:

js

export default {

created() {

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

// ...

})

}

}

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

停止偵聽器 ​

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

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

js

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

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

unwatch()

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