目录
(1)普通监视
(2)深度监视
data下面的numbers有多个属性
watch监视多级结构中【 某个 】属性的变化
监视多级结构中【 所有 】属性的变化
(3)监视属性的全局写法和简写
全局写法
简写
(4)对比计算属性
定时器案例 -- 用监视属性
(1)普通监视
监视属性watch:
1.当被监视的属性变化时, 回调函数自动调用, 进行相关操作
2.监视的属性必须存在,才能进行监视!!
3.监视的两种写法:
(1).new Vue时传入watch配置
(2).通过vm.$watch监视 (全局)
<body>
<!-- 准备好一个容器-->
<div id="root">
<h2>今天天气很{{info}}</h2>
<button @click="changeWeather">切换天气</button>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
const vm = new Vue({
el: '#root',
data: {
isHot: true,
},
methods: {
changeWeather() {
this.isHot = !this.isHot
}
},
computed: {
info() {
return this.isHot ? '炎热' : '凉爽'
}
},
// 监视属性
watch:{
监视的对象{监视的人}
isHot:{
// 没加,刚刚打开不执行,加了,初始化时让handler调用一下,就执行了
immediate:true,
// handler什么时候调用? 【当isHot发生改变时。】
handler(newValue, oldValue){
console.log('isHot被修改了', newValue, oldValue)
}
}
}
})
</script>
==================== 监视属性的属性方法 ======================
1、immediate: true, 没加,刚刚打开不执行,加了,初始化时让 handler方法 调用一下,就执行了
2、handler(newValue, oldValue) { }方法 :handler什么时候调用? 【当监视对象(人)发生改变时。】
handler(newValue, oldValue) { console.log('isHot被修改了', newValue, oldValue) }
- newValue -- 现在所在的状态 oldValue -- 前一个状态
(2)深度监视
深度监视:
(1).Vue中的watch默认不监测对象内部值的改变(一层)。
(2).配置deep:true可以监测对象内部值改变(多层)。
备注:
(1).Vue自身可以监测对象内部值的改变,但Vue提供的 watch 默认不可以!
(2).使用 watch 时根据数据的具体结构,决定是否采用深度监视。
data下面的numbers有多个属性
watch监视多级结构中【 某个 】属性的变化
【注意:多个单词和多层结果,需要加 引号 ,上面不加是简写,实际上,这个是键值,需要加上去】
watch: { //监视多级结构中【 某个 】属性的变化 'numbers.a':{ handler(){ console.log('a被改变了') } } }
监视多级结构中【 所有 】属性的变化
deep: true, deep 的意思就是深入观察,监听器会一层层的往下遍历,给对象的所有属性都加上这个监听器
【注意】但是这样性能开销就会非常大了,任何修改obj里面任何一个属性都会触发这个监听器里的 handler。
watch: { // 监视多级结构中【 所有 】属性的变化 numbers: { deep: true, handler() { console.log('numbers改变了') } } }
(3)监视属性的全局写法和简写
全局写法
需要给Vue实例对象赋值给一个变量vm,
全局配置下,用该实例变量调用,还需要加一个 $ ,
注意:全局监视下,监视的对象需要加引号,不加就是监视变量了 , this指向还是Vue实例
简写
条件:只用了 handle()方法,且不用其他属性
- 写在实例里面
watch: { // (1)正常写法 small:{ // immediate:true, //初始化时让handler调用一下 // deep:true,//深度监视 handler(newValue,oldValue){ console.log('small被修改了',newValue,oldValue) } }, // (2)简写【注意:需要配置项(例如deep深度监视)时,就不能使用简写形式】 isHot(newValue,oldValue){ console.log('isHot被修改了',newValue,oldValue,this) } }
- 写在实例外面
// (1)正常写法 vm.$watch('small',{ immediate:true, //初始化时让handler调用一下 deep:true, //深度监视 handler(newValue,oldValue){ console.log('small被修改了',newValue,oldValue) } }) // (2)简写(箭头函数Vue 指向window) vm.$watch('isHot', function(newValue, oldValue) { console.log('isHot被修改了', newValue, oldValue, this) })
(4)对比计算属性
computed和watch之间的区别:
1. computed能完成的功能,watch都可以完成。
2. watch能完成的功能,computed不一定能完成,例如:watch可以进行异步操作,当面临异步的时候,用watch更好,因为computed 是靠返回值return
两个重要的小原则:
1. 所被Vue管理的函数,最好写成普通函数,这样this的指向才是vm 或 组件实例对象。
2. 所有不被Vue所管理的函数(定时器的回调函数、ajax的回调函数等、Promise的回调函数),最好写成箭头函数,这样this的指向才是vm 或 组件实例对象。
备注:
1. 使用普通函数,因为定时器是window下的,this直接指向window
2. 使用箭头函数,就可以找到,箭头函数本身没有this指向,会向上查找,找到监视的对象,他是Vue管理的函数,所以this指向vm
定时器案例 -- 用监视属性
<body>
<!-- 准备好一个容器-->
<div id="root">
姓:<input type="text" v-model="firstName"> <br /><br /> 名:
<input type="text" v-model="lastName"> <br /><br /> 全名:
<span>{{fullName}}</span> <br /><br />
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
const vm = new Vue({
el: '#root',
data: {
firstName: '张',
lastName: '三',
fullName: '张-三'
},
// 当面临异步的时候,用watch更好,因为computed 是靠返回值return
watch: {
// 不需要配置项,可以简写
firstName(val) {
// 当需要异步任务时候,用不了计算属性,只能用监视属性
setTimeout(() => {
console.log(this)
this.fullName = val + '-' + this.lastName
}, 1000);
},
lastName(val) {
this.fullName = this.firstName + '-' + val
}
}
})
</script>