监视属性
监视属性就是监视某一个属性的变化。
new Vue({
el:"",//关联界面元素
data:{x:12},//vm的数据源
methods:{},//方法
filter:{},//过滤器
computed:{xx(){}}, //xx就是一个计算属性
watch:{x(){}} //x就是监听了data中的x属性的一个监听器
})
watch:{x(){}}中的方法名必须跟要监听的data中的属性名一样,才代表监听指定属性。当监听器监听的属性发生变化时,就会调用watch中对应的方法,监视的属性必须存在,才能进行监视。监听器属性,比计算属性计算效率消耗大
第1种方法实现监视
<div id="app">
<h2>今天天气很{{info}}</h2>
<br>
<button @click="change">切换天气</button>
</div>
<script>
new Vue({
el:"#app",
data:{
isHost:true,
},
methods: {
change(){
this.isHost=!this.isHost;
}
},
computed:{
info(){
return this.isHost ? "炎热" : "凉爽";
}
},
watch:{
isHost:{
// 默认为false,如果为true初始化时会调用一次
immediate:true,
// handler会在isHost发生改变时调用
handler(newvalue,oldvalue){
console.log("isHost被修改了",newvalue,oldvalue);
}
},
info(newvalue,oldvalue){
console.log("info被修改了",newvalue,oldvalue);
}
}
})
</script>
watch中的方法可以传入两个参数,第1个参数用于记录被修改后的值,第2个参数用于记录被修改前的值,初始化时被调用不存在被修改之前的值所以会是undefined。计算属性也可以被监听
第2种方法实现监视
let vm=new Vue({
el:"#app",
data:{
isHost:true,
}
});
vm.$watch("isHost",{
// 默认为false,如果为true初始化时会调用一次
immediate:fale,
// handler会在isHost发生改变时调用
handler(newvalue,oldvalue){
console.log("isHost被修改了",newvalue,oldvalue);
})
第2种方法必须要在创建的Vue实例生成之后才能使用,第1个参数是要监视的属性名,此时属性名必须要加引号否则会当作变量取值就会报错,第2个参数需要传入一个对象就是监视配置项。
深度监视
深度监视用于监视多级结构中所有属性的变化,当多级结构其中一个属性变化也会被监听。
创建的Vue实例中的watch默认不监听对象内部属性值的改变,配置deep为true就可以监听对象内部属性值的改变。
创建的Vue实例自身可以监听对象内部属性值的改变只是其提供的watch默认不可以,使用时需要根据数据的具体结构决定是否采用深度监视。
number:{
handler(){
console.log("number被改变了");
}
}
这样只会监视number这个整体对象不会监视对象中的属性,只有number这个对象的引用改变了才会调用watch中的方法
<div id="app">
<h2>今天天气很{{info}}</h2>
<br>
<button @click="change">切换天气</button>
<h2>{{number.a}}</h2>
<br><button @click="add">点击让值加1</button>
<h2>{{number.b}}</h2>
<br><button @click="minus">点击让值减1</button>
</div>
<script>
new Vue({
el:"#app",
data:{
isHost:true,
number:{
a:1,
b:7
}
},
methods: {
change(){
this.isHost=!this.isHost;
},
add(){
this.number.a++;
},
minus(){
this.number.b--;
}
},
computed:{
info(){
return this.isHost ? "炎热" : "凉爽";
}
},
watch:{
isHost:{
// 默认为false,如果为true初始化时会调用一次
immediate:false,
// handler会在isHost发生改变时调用
handler(newvalue,oldvalue){
console.log("isHost被修改了",newvalue,oldvalue);
}
},
info(newvalue,oldvalue){
console.log("info被修改了",newvalue,oldvalue);
},
number:{
// 深度监视开启,默认为false
deep:true,
handler(){
console.log("number被改变了");
}
}
}
})
</script>
监听属性的简写形式
简写形式的前提是不需要immediate以及deep的配置项,只有handler回调函数时就可以简写。
第1种方法
info(newvalue,oldvalue){
console.log("info被修改了",newvalue,oldvalue);
}
需要监听的属性用作函数名,函数就相当于配置项中的handler
第2种方法
完整写法
vm.$watch("isHost",{
// 默认为false,如果为true初始化时会调用一次
immediate:fale,
deep;true,
// handler会在isHost发生改变时调用
handler(newvalue,oldvalue){
console.log("isHost被修改了",newvalue,oldvalue);
简写
vm.$watch("isHost",function(newvalue,oldvalue){
console.log("isHost被修改了",newvalue,oldvalue);
}
//第1个参数相同,第2个参数需要传一个回调函数
ps:所有Vue管理的函数都不能写箭头函数,否则this不再指向创建的Vue实例
监听属性和计算属性的区别
1.computed能完成的功能,watch都可以完成
2.watch完成的功能,computed不一定能完成,比如watch中可以执行异步操作
3.所有Vue管理的函数需要写成普通函数,这样this才指向创建的Vue实例,但是不被Vue管理的函数比如定时器的回调函数,AJAX网络请求的回调函数以及Promise的回调函数,需要写为箭头函数,这样this才指向箭头函数外层作用域就是创建的Vue实例
<div id="app">
firstName:<input type="text" v-model="firstName"><br><br>
lastName:<input type="text" v-model="lastName"><br><br>
fullName:<span>{{fullName}}</span>
</div>
<script>
new Vue({
el:"#app",
data:{
firstName:"jung",
lastName:"jessica",
fullName:"jessica-jung"
},
watch:{
firstName(val){
setTimeout(()=>{
this.fullName=this.lastName+"-"+val;
},1000)
},
lastName(val){
setTimeout(()=>{
this.fullName=val+"-"+this.firstName;
},1000)
}
}
});
</script>