Vue中watch用法
当需要在数据变化时执行异步或开销较大的操作时,使用侦听器 watch
的方式是最有用的
- 监听某一数据的变化
- 监听对象或数组的变化
- 监听对象或数组某一属性的变化
- 监听路由的变化
监听某一数据的变化
<template>
<div>
<!-- 侦听器:当需要在数据变化时执行异步或开销较大的操作时,使用侦听器 watch 方式是最有用的 -->
<input type="text" v-model="firstName"> +
<input type="text" v-model="lastName"> =
<input type="text" v-model="fullName">
</div>
</template>
<script>
export default {
name: 'watch',
data() {
return {
firstName: 'ff',
lastName: 'll',
fullName: '',
}
},
watch: {
// 1.监听某一数据的变化
firstName(newVal, oldVal) {
console.log('firstName:',newVal + ' ' + oldVal)
this.fullName = newVal + ' ' + this.lastName
},
lastName(newVal, oldVal) {
console.log('lastName:',newVal + ' ' + oldVal)
this.fullName = this.firstName + ' ' + newVal
}
},
}
</script>
这种方式有一个缺点,就是当值第一次绑定的时候不会执行监听函数,只有当值改变的时候才会执行。
immediate和handler
如果我们想在第一次绑定的时候执行此监听函数,则需要设置 immediate: true
watch: {
firstName: {
handler(newVal, oldVal) {
console.log('firstName:',newVal + ' ' + oldVal)
this.fullName = newVal + ' ' + oldVal
},
immediate: true
},
lastName: {
handler(newVal, oldVal) {
console.log('lastName:',newVal + ' ' + oldVal)
this.fullName = this.firstName + ' ' + newVal
},
immediate: true
}
},
注意:
- 监听的数据后面写成对象的形式,包含
handler
方法和immediate
,之前我们写的函数其实就是在使用handler
方法。 immediate
表示watch
中首次绑定的时候,是否执行handler
,值为true
,表示在watch
中声明的时候,就立即执行handler
方法,值为false
,则和一般使用watch
一样,在数据发生变化的时候才执行handler
。
监听对象或数组的变化
当需要监听对象或数组的变化时,需要设置 deep: true
,否则监听不对对象的变化
deep
<template>
<div>
<input type="text" v-model="goods.price">
</div>
</template>
<script>
export default {
name: 'watch',
data() {
return {
goods: {
price: 15,
width: 1,
},
}
},
watch: {
goods: {
handler(newVal, oldVal) {
console.log(newVal + ' ' + oldVal)
},
immediate: true,
deep: true
},
},
}
</script>
当需要监听一个对象的改变时,普通的 watch
方法无法监听到对象内部属性的改变,只有 data
中的数据才能够监听到变化,此时需要 deep
属性来对对象进行深度监听。
注意:
设置 deep: true
则可以监听到对象内部属性的变化,此时,会给对象内部的所有属性都加上这个监听器,当对象属性较多时,每个属性值的变化都会执行 handler
,如果只需要监听对象中的一个属性值,则可以做一下优化-——使用字符串的形式监听对象属性。如下:
监听对象或数组某一属性的变化
watch: { // 键路径必须加上引号
'goods.price': {
handler(newVal, oldVal) {
console.log(newVal, oldVal)
},
immediate: true,
// deep: true 不用使用 deep
}
},
监听路由的变化
watch: {
'$route.path': function(newVal, oldVal) {
console.log(newVal, oldVal)
if (newVal == '/slot') {
console.log('欢迎进入 slot 页面')
} else if (newVal == '/computed') {
console.log('欢迎进入计算页面')
}
}
},
$route(to, from) { // to是到哪去,from 是从哪来
console.log(to.path, from)
}