属性监听器

138 阅读2分钟

监视属性

监视属性就是监视某一个属性的变化。

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。计算属性也可以被监听

image.png

image.png

第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>