淺談vue.watch的觸發(fā)條件是什么
很多人習(xí)慣用watch,但是卻很少有人知道watch的真正觸發(fā)條件。如果不是對vue原理了如指掌,請謹(jǐn)慎使用watch。
示例1,下面會觸發(fā)watch 嗎?
<script>
new Vue({
data() {
return {
city: {id: 1, name: 'Beijing'}
}
},
watch: {
city() {
console.log('city changed')
}
},
created() {
this.city = {id: 1, name: 'Beijing'}
}
})
</script>
會觸發(fā),因為在created方法里面重新給city賦值了一個對象,city前后的指向不同了
示例2:
<script>
new Vue({
data() {
return {
city: {id: 1, name: 'Beijing'}
}
},
watch: {
city() {
console.log('city changed')
}
},
created() {
this.city.name = 'Shanghai'
}
})
</script>
不會觸發(fā), 因為created方法執(zhí)行之后, city的指向沒有變
如果我們期望捕獲這種更新,應(yīng)該這樣寫代碼:
watch: {
city: {
handler: () => console.log('city changed'),
deep: true
}
}
將選項deep設(shè)為true能讓vue捕獲對象內(nèi)部的變化。
下面討論一下watch一個數(shù)組:
<script>
new Vue({
el: '#body',
data() {
return {
cities: ['Beijing', 'Tianjin']
}
},
watch: {
cities() {
console.log('cities changed')
}
}
})
</script>
那下面哪些操作會觸發(fā)cities的watch回調(diào)呢?
this.cities = ['Beijing', 'Tianjin']
this.cities.push('Xiamen')
this.cities = this.cities.slice(0, 1)
this.cities.pop();
this.cities.sort((a,b)=>a.localeCompare(b));
this.cities[0] = 'Shenzhen'
this.cities.splice(0, 1)
this.cities.length = 0
答案是只有最后三行不會觸發(fā)。
補(bǔ)充知識:vue 深度watch與watch立即觸發(fā)回調(diào)
基礎(chǔ)用法
搜索框輸入搜索關(guān)鍵字的時候,可以自動觸發(fā)搜索,此時除了監(jiān)聽搜索框的change事件之外,我們也可以通過watch監(jiān)聽搜索關(guān)鍵字的變化。
<template>
<div>
<span>搜索</span>
<input v-model="searchVal" />
</div>
</template>
<script>
export default {
data() {
return {
searchVal: ''
}
},
watch: {
// 在值發(fā)生變化之后,重新加載數(shù)據(jù)
searchVal(newValue, oldValue) {
if (newValue !== oldValue) {
this.loadData()
}
}
},
methods: {
loadData() {
// 重新加載數(shù)據(jù),此處需要通過函數(shù)防抖
}
}
}
</script>
立即觸發(fā)
通過上面的代碼,現(xiàn)在已經(jīng)可以在值發(fā)生變化的時候觸發(fā)加載數(shù)據(jù)了,但是如果要在頁面初始化時候加載數(shù)據(jù),我們還需要在created或者mounted生命周期鉤子里面再次調(diào)用loadData方法。不過,現(xiàn)在可以不用這樣寫了,通過配置watch的立即觸發(fā)屬性,就可以滿足了。
export default {
watch: {
// 在值發(fā)生變化之后,重新加載數(shù)據(jù)
searchValue: {
// 通過handler來監(jiān)聽屬性變化, 初次調(diào)用 newValue為""空字符串, oldValue為 undefined
handler(newValue, oldValue) {
if (newValue !== oldValue) {
this.loadData()
}
},
// 配置立即執(zhí)行屬性
immediate: true
}
}
}
深度監(jiān)聽
一個表單頁面,需求希望用戶在修改表單的任意一項之后,表單頁面就需要變更為被修改狀態(tài)。如果按照上例中watch的寫法,那么我們就需要去監(jiān)聽表單每一個屬性,太麻煩了,這時候就需要用到watch的深度監(jiān)聽deep
export default {
data() {
return {
formData: {
name: '',
sex: '',
age: 0,
deptId: ''
}
}
},
watch: {
// 在值發(fā)生變化之后,重新加載數(shù)據(jù)
formData: {
// 需要注意,因為對象引用的原因, newValue和oldValue的值一直相等
handler(newValue, oldValue) {
// 在這里標(biāo)記頁面編輯狀態(tài)
},
// 通過指定deep屬性為true, watch會監(jiān)聽對象里面每一個值的變化
deep: true
}
}
}
隨時監(jiān)聽,隨時取消,了解一下$watch
有這樣一個需求,有一個表單,在編輯的時候需要監(jiān)聽表單的變化,如果發(fā)生變化則保存按鈕啟用,否則保存按鈕禁用。
這時候?qū)τ谛略霰韱蝸碚f,可以直接通過watch去監(jiān)聽表單數(shù)據(jù)(假設(shè)是formData),如上例所述,但對于編輯表單來說,表單需要回填數(shù)據(jù),這時候會修改formData的值,會觸發(fā)watch,無法準(zhǔn)確的判斷是否啟用保存按鈕?,F(xiàn)在你就需要了解一下$watch
export default {
data() {
return {
formData: {
name: '',
age: 0
}
}
},
created() {
this.$_loadData()
},
methods: {
// 模擬異步請求數(shù)據(jù)
$_loadData() {
setTimeout(() => {
// 先賦值
this.formData = {
name: '子君',
age: 18
}
// 等表單數(shù)據(jù)回填之后,監(jiān)聽數(shù)據(jù)是否發(fā)生變化
const unwatch = this.$watch(
'formData',
() => {
console.log('數(shù)據(jù)發(fā)生了變化')
},
{
deep: true
}
)
// 模擬數(shù)據(jù)發(fā)生了變化
setTimeout(() => {
this.formData.name = '張三'
}, 1000)
}, 1000)
}
}
}
根據(jù)上例可以看到,我們可以在需要的時候通過this.$watch來監(jiān)聽數(shù)據(jù)變化。那么如何取消監(jiān)聽呢,上例中this.$watch返回了一個值unwatch,是一個函數(shù),在需要取消的時候,執(zhí)行 unwatch()即可取消
以上這篇淺談vue.watch的觸發(fā)條件是什么就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
axios 實現(xiàn)post請求時把對象obj數(shù)據(jù)轉(zhuǎn)為formdata
今天小編就為大家分享一篇axios 實現(xiàn)post請求時把對象obj數(shù)據(jù)轉(zhuǎn)為formdata,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-10-10
Vue 3中常用的生命周期鉤子和監(jiān)聽器的操作方法
這篇文章主要介紹了Vue 3中常用的生命周期鉤子和監(jiān)聽器的操作方法,分析常用的一些生命周期鉤子和監(jiān)聽器可以幫助我們在組件中處理數(shù)據(jù)加載、狀態(tài)變化和響應(yīng)式更新,需要的朋友可以參考下2024-07-07
MAC+PyCharm+Flask+Vue.js搭建系統(tǒng)
最近新做了個項目,使用的是MAC+PyCharm+Flask+Vue.js搭建系統(tǒng),本文就來分享一下搭建步驟,感興趣的可以了解一下2021-05-05

