监视/侦听属性【watch】
用于监视某一个属性的变化
监视属性watch:
1.当被监视的属性变化时, 回调函数【handler()】自动调用, 进行相关操作
2.监视的属性必须存在,才能进行监视!!【监视不存在的属性不会报错】
3.配置监视的两种写法:
(1).new Vue时传入watch配置
(2).通过vm.$watch监视
watch中的配置项:
配置项名称 | 值 | 含义 |
---|---|---|
immediate | true/false | 初始化时让handler调用一下 |
handler | function(){} | 当监视的属性发生改变时要调用的函数 |
deep | true/false | 是否开启深度监视,见“九、1.深度监视” |
<body>
<div id="root">
<h2>今天天气很{{info}}</h2>
<button type="button" @click="switchWeather">切换天气</button>
</div>
<script type="text/javascript">
//阻止 vue 在启动时生成生产提示。
Vue.config.productionTip = false
const vm = new Vue({
el: "#root",
data:{
isHot: true
},
computed:{
info(){
return this.isHot ? '炎热' : '凉爽'
}
},
methods:{
switchWeather(){
this.isHot = !this.isHot
}
},
// 配置监视的第一种方式
// watch:{
// isHot:{
// immediate:true, //初始化时让handler调用一下
// //handler方法被调用时,会将newValue(变化之后的值), oldValue(变化之前的值)两
// //个参数传给handler方法,我们可以拿来用
// handler(newValue,oldValue){
// console.log('isHot变了',newValue,oldValue)
// }
// }
// }
});
// 配置监视的第二种方式
// 第一个参数一定要传入字符串
// watch可以监视data中的属性,也可以监视计算属性
// 配置对象{}中的key原始写法是'info',可以简写为info。这里的'info'并不在配置对象中,所以不能
// 简写,这里如果直接写info,就会去查找info变量了,而我们的本意是传一个字符串
vm.$watch('info',{
immediate:true, //初始化时让handler调用一下
handler(newValue,oldValue){
console.log('info变了',newValue,oldValue)
}
})
</script>
</body>
1. 深度监视
深度监视:
(1).Vue中的watch默认不监测data中对象内部值的改变(一层)。
(2).配置deep:true可以监测对象内部值改变(多层)。
备注:
(1).Vue自身可以监测对象内部值的改变,但Vue提供的watch默认不可以【为了存在多级结构时不影响效率】!
(2).使用watch时根据数据的具体结构,决定是否采用深度监视。
<body>
<!-- 准备好一个容器-->
<div id="root">
<h2>今天天气很{{info}}</h2>
<button @click="changeWeather">切换天气</button>
a的值是{{numbers.a}}
<button @click="numbers.a++">点我</button>
<button @click="numbers = {a:666,b:888}">点我</button>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
const vm = new Vue({
el:'#root',
data:{
isHot:true,
numbers: {
a: 1,
b: 1
}
},
computed:{
info(){
return this.isHot ? '炎热' : '凉爽'
}
},
methods: {
changeWeather(){
this.isHot = !this.isHot
}
},
watch:{
//监视多级结构中某个属性的变化【多级结构中某个属性的变化会触发handler方法的调用】
'numbers.a':{
// immediate:true, //初始化时让handler调用一下
//handler什么时候调用?当isHot发生改变时。
handler(newValue,oldValue){
console.log('numbers.a',newValue,oldValue)
}
},
// 监视多级结构中任意属性的变化【多级结构中任意一个属性的变化都会触发handler方法的调用】
numbers:{
deep: true,
handler(){
console.log('numbers改变了')
}
}
}
})
</script>
2. 监视的简写形式
前提:配置项仅有handler时就可以开启监视的简写形式
如何简写
//这里给出了两种配置监视方式的简写形式
watch:{
//正常写法
/* isHot:{
// immediate:true, //初始化时让handler调用一下
// deep:true,//深度监视
handler(newValue,oldValue){
console.log('isHot被修改了',newValue,oldValue)
}
}, */
//简写
/* isHot(newValue,oldValue){
console.log('isHot被修改了',newValue,oldValue,this)
} */
}
//正常写法
/* vm.$watch('isHot',{
immediate:true, //初始化时让handler调用一下
deep:true,//深度监视
handler(newValue,oldValue){
console.log('isHot被修改了',newValue,oldValue)
}
}) */
//简写
//注:这里的function也属于Vue管理的函数,不能写成箭头函数的形式,否则this的指向也会有问题
vm.$watch('isHot',function(newValue,oldValue){
console.log('isHot被修改了',newValue,oldValue,this)
})
3. 计算属性VS监视属性
监视属性:可以开启异步任务
<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: {
firstName(newValue){
// 这里的定时器确实是在Vue管理的函数【firstName】中开启的,但定时器所指定的回调函数【箭头函数】是不受Vue控制的,是由浏览器定时器管理模块控制的,回调函数也是由js引擎调用的
setTimeout(()=>{
// 这里的定时器回调函数如果写为箭头函数,由于箭头函数是没有this的,就会往外找,也就找到了firstName这个函数,最后输出的this就是firstName的this,也就是Vue实例;
// 这里的定时器回调函数如果写为普通函数,那么this就是Window实例
console.log(this)
this.fullName = newValue + '-' + this.lastName
}, 1000)
},
lastName(newValue){
this.fullName = this.firstName + '-' + newValue
}
}
})
</script>
计算属性:不能开启异步任务去维护数据
<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:'三',
},
computed:{
fullName(){
console.log('get被调用了')
// setTimeout:单位是毫秒
setTimeout(()=>{
// 这里的return并不是fullName的返回值,而是箭头函数的返回值
// 也就是说,这样写fullName函数的返回值是undefined,因此取不到fullName的值
return this.firstName + '-' + this.lastName
}, 1000)
}
}
})
</script>
各自的应用场景:
- 当同一个功能计算属性和监视属性都能实现时优先使用计算属性
- 当需要进行异步计算时只能使用监视属性【这是因为监视属性并不是依靠返回值给监视的属性赋值的,而计算属性是完全依靠返回值进行赋值的】
watch:命令式
computed和watch之间的区别:
1.computed能完成的功能,watch都可以完成。
2.watch能完成的功能,computed不一定能完成,例如:watch可以进行异步操作。
两个重要的小原则:【总之,我们的目的就是让函数内部的this指向Vue的实例,这样以后在我们需要使用Vue实例身上的东西时,我们能够通过this进行调用】
1.所有被Vue管理的函数,最好写成普通函数,这样this的指向才是vm 或 组件实例对象。
2.所有不被Vue所管理的函数(定时器的回调函数、ajax的回调函数等、Promise的回调函数),最好写成箭头函数,这样this的指向才是vm 或 组件实例对象。
标签:isHot,Vue,2x,watch,handler,监视,侦听,newValue
From: https://www.cnblogs.com/wzzzj/p/18039947