7. 侦听属性
侦听属性的基本用法
watch监听属性
- 当被监听的属性发送变化时,回调函数自动调用,进行相关操作。
- 监听的属性必须是存在的,才能进行监听。
- 既可以监听
data
,也可以监听计算属性
。 - watch一般写在组件内,组件的注销watch也会随之注销。
watch的三个参数
handler
:其值是一个回调函数,即监听到变化时应该执行的函数。
handler(newValue, oldValue)
deep
:其值是true或false,确认是否深入监听,默认值为false。immediate
:其值是true或false,确认是否以当前的初始值执行handler函数(一上来就执行,无需等到数据发生改变),默认值为false。
watch的两种写法
- 创建Vue时传入
watch: {}
配置项。 - 通过
vm.$watch()
监听。
<div id="room">
<h1>
今天天气很{{info}}
</h1>
<button @click="isHot = !isHot">切换天气</button>
</div>
<script>
const vm = new Vue({
el: '#room',
data: {
isHot: true
},
computed: {
info() {
return this.isHot ? '炎热' : '凉爽'
}
},
methods: {
},
//第一种写法
watch: {
info: {
handler(newValue, oldValue) {
console.log('info被修改了', newValue, oldValue)
}
}
}
})
//第二种写法
// vm.$watch('isHot', {
// handler(newValue, oldValue) {
// console.log('info被修改了', newValue, oldValue)
// }
// })
</script>
deep深度监听
- Vue中watch默认不监听对象内部值的改变。
<div id="room">
<h1>
今天天气很{{info}}
</h1>
<button @click="isHot = !isHot">切换天气</button>
</hr>
<h3>a的值是:{{number.a}}</h3>
<button @click="number.a++">点击a+1</button>
</div>
<script>
const vm = new Vue({
el: '#room',
data: {
isHot: true,
number: {
a: 1
}
},
computed: {
info() {
return this.isHot ? '炎热' : '凉爽'
}
},
watch: {
number: {
//此时点击btn使a++,number.a改变了,但无法触发监听器
handler(newValue, oldValue) {
console.log('number改变了')
}
}
}
})
</script>
解决方法一(字符串形式)
<div id="room">
<h1>
今天天气很{{info}}
</h1>
<button @click="isHot = !isHot">切换天气</button>
</hr>
<h3>a的值是:{{number.a}}</h3>
<button @click="number.a++">点击a+1</button>
</div>
<script>
const vm = new Vue({
el: '#room',
data: {
isHot: true,
number: {
a: 1
}
},
computed: {
info() {
return this.isHot ? '炎热' : '凉爽'
}
},
watch: {
//将number写成number.a,必须加上引号
'number.a': {
handler(newValue, oldValue) {
console.log('number改变了')
}
}
}
})
</script>
虽然这样能解决问题,但是如果number不止a一个属性,有100个,1000个怎么办?如果都写的话代码量就会很大,此时就出现了deep
深度监听。
解决方法二(deep)
<div id="room">
<h1>
今天天气很{{info}}
</h1>
<button @click="isHot = !isHot">切换天气</button>
</hr>
<h3>a的值是:{{number.a}}</h3>
<button @click="number.a++">点击a+1</button>
</div>
<script>
const vm = new Vue({
el: '#room',
data: {
isHot: true,
number: {
a: 1
}
},
computed: {
info() {
return this.isHot ? '炎热' : '凉爽'
}
},
watch: {
number: {
deep: true,
handler(newValue, oldValue) {
console.log('number改变了')
}
}
}
})
</script>
这个时候就可以使用deep深入观察,监听器会一层层的往下遍历,给对象的所有属性都加上这个监听器,但是这样消耗过大。
如果监听的属性很少
,那么使用字符串形式是比较合理的,监听的属性过多
时,使用deep进行深度监听。
watch简写
当监听属性除了handler没有其它配置项时,可以进行简写。
<script>
//第一种简写形式
new Vue({
...
watch: {
isHot(newValue, oldValue) {
console.log('isHot被修改了', newValue, oldValue)
}
}
...
})
//第二种简写形式
vm.$watch('isHot', function(newValue, oldValue) {
console.log('isHot被修改了', newValue, oldValue)
})
</script>
计算属性VS侦听属性
- computed能完成的,watch都能完成。
- watch能完成的,computed不一定能完成,例如watch可以进行异步操作(在合适的场景加入异步操作能交互效果更佳)。
<!-- 姓名案例 -->
<div id="room">
姓:<input type="text" v-model="firstName"></br>
名: <input type="text" v-model="lastName"></br>
姓名:<span>{{fullName}}</span>
</div>
使用计算属性实现
new Vue({
el: '#room',
data: {
firstName: 'R',
lastName: 'cloud'
},
computed: {
//一般只读取属性值而不修改,所以简写只读取属性值
fullName() {
return this.firstName + '-' + this.lastName
}
}
})
使用监听属性实现
new Vue({
el: '#room',
data: {
firstName: 'R',
lastName: 'cloud',
fullName: 'R-cloud'
},
watch: {
// (newValue, oldValue)只写一个参数时默认是newValue
// 监听实现可以加入异步任务,例如修改完姓一秒后再显示
firstName(val) {
setTimeout(()=> {
this.fullName = val + '-' + this.lastName
}, 1000)
},
lastName(val) {
this.fullName = this.firstName + '-' + val
}
}
})
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步