Vue:计算属性及监听

一、计算属性:

1. 定义:计算属性是通过已有属性,计算的来的属性

2. 原理:计算属性底层借助了Object.defineProperty()方法提供的gettersetter

3. get()函数:

  • get函数在初次读取时会执行一次
  • 当计算属性所依赖的数据发生改变的时候,get()函数会被再次调用

4. 优势:与methods实现相比,计算属性采用了缓存机制在获取计算属性的属性值时,若所依赖的属性没有发生变化,那么就不会执行get()函数而是将缓存的计算属性值返回。与methods每次都会执行计算逻辑相比,效率更高。

  • 计算属性底层通过Object.defineProperty()方法,最终会添加到vm上,因此使用之和获取普通属性相同。
  • 如果要修改计算属性(这种需求不是很多),那么必须写set()函数去相应修改,且set()函数中要引起计算时依赖的数据发生改变,这样获取计算属性时才会被重新计算。
  • 如果计算属性只是用于展示,没有人为修改的需求,可以使用计算属性的简写形式。
    <div id="app">
        姓:<input type="text" v-model:value="firstName"><br/>
        名:<input type="text" v-model:value="lastName"><br/>
        全名:<span>{{fullName}}</span>
    </div>

    <script>
        const vm = new Vue({
            el:'#app',
            data:{
                firstName:'wang',
                lastName:'y'
            },
            computed:{
                fullName:{
                    get(){
                        return this.firstName+'-'+this.lastName;
                    },

                    set(value){
                        const arr = value.split('-');
                        this.firstName=arr[0];
                        this.lastName=arr[1];
                    }
                }

                // 如果没有set函数,可以采用如下的简写形式
                // fullName(){
                //     return this.firstName+'-'+this.lastName;
                // }
            }
        });
    </script>

二、监视属性

2.1 监视属性基础

1.  监视属性用于监视属性的变化,当被监视的属性发生变化后,回调函数自动调用,进行相应的操作。

2.  被监视的属性必须存在,才能进行监视

3. 监视的两种写法:

  • 在vue实例创建时,配置其watch配置;
  • 通过vm.$watch添加监视;

4. 配置项属性:immediated:false,该属性默认为false,改为true之后,则初始化时会立即调用一次handler(newValue,oldValue)。

    <div id="app">
        <h3>今天天气很{{info}}</h3>
        <button @click="changeWeather()">切换天气</button>
    </div>
    
    <script>
        const vm = new Vue({
            el:'#app',
            data:{
                isHot:true,
            },
            computed:{
                info:{
                    get(){
                        return this.isHot?'炎热':'凉爽'
                    }
                }
            },
            methods: {
                changeWeather(){
                    this.isHot = !this.isHot
                }
            },
            // 监视写法一
            // watch:{
            //     // 被监视的属性
            //     isHot:{
            //         // 属性变化的回调函数
            //         handler(newValue,oldValue){
            //             console.log('属性isHot被修改了',newValue,oldValue);

            //         },
            //         // immediate:true,  // 该参数设置为true,可以在初始化的时候让handler调用一下     
            //     }
            // }
        });

        // 监视写法二
        vm.$watch('isHot',{
                    immediate:true,  // 该参数设置为true,可以在初始化的时候让handler调用一下     
                    // 属性变化的回调函数,即isHot发生变化是该函数被调用
                    handler(newValue,oldValue){
                        console.log('属性isHot被修改了',newValue,oldValue);

                    }, 
        })
    </script>

2.2 深度监视

深度监视

  • Vue中的watch默认不监视对象内部值的改变(一层)。
  • 配置deep:true可以达到监测对象内部值改变的目的(二层)。

备注:

  • Vue自身可以监测对象内部值的改变,但Vue提供的watch默认不可以;
  • 使用watch时根据数据的具体结构,决定是否采用深度监视。
    <div id="app">
        <h3>今天天气很{{info}}</h3>
        <button @click="changeWeather()">切换天气</button>
        <hr/>
        <h3>a的值为:{{numbers.a}}</h3>
        <button @click="numbers.a++">a+1</button>
        <hr/>
        <h3>b的值为:{{numbers.b}}</h3>
        <button @click="numbers.b++">b+1</button>
    </div>
    
    <script>
        const vm = new Vue({
            el:'#app',
            data:{
                isHot:true,
                numbers:{
                    a:1,
                    b:1
                }
            },
            computed:{
                info:{
                    get(){
                        return this.isHot?'炎热':'凉爽'
                    }
                }
            },
            methods: {
                changeWeather(){
                    this.isHot = !this.isHot
                }
            },
            // 监视写法一
            watch:{
                // 被监视的属性
                isHot:{
                    // 属性变化的回调函数
                    handler(newValue,oldValue){
                        console.log('属性isHot被修改了',newValue,oldValue);
                    },
                    // immediate:true,  // 该参数设置为true,可以在初始化的时候让handler调用一下     
                },
                // // 监视多级结构中某个属性的比变化
                // 'numbers.a':{
                //     handler(){
                //         console.log('a被改变了!');
                //     }
                // }

                // 监视多级结构中所有属性的变化
                numbers:{
                    deep:true, // 开启深度监视
                    handler(){
                        console.log('number发生改变!');
                    }

                }

            }
        });

        // // 监视写法二
        // vm.$watch('isHot',{
        //             immediate:true,  // 该参数设置为true,可以在初始化的时候让handler调用一下     
        //             // 属性变化的回调函数,即isHot发生变化是该函数被调用
        //             handler(newValue,oldValue){
        //                 console.log('属性isHot被修改了',newValue,oldValue);

        //             }, 
        // })
    </script>

2.3 监视简写

        如果监视属性中除了handler()回调函数,没有其他的配置项,那么可以采用简写形式:

    <div id="app">
        <h3>今天天气很{{info}}</h3>
        <button @click="changeWeather()">切换天气</button>
    </div>
    
    <script>
        const vm = new Vue({
            el:'#app',
            data:{
                isHot:true,
            },
            computed:{
                info:{
                    get(){
                        return this.isHot?'炎热':'凉爽'
                    }
                }
            },
            methods: {
                changeWeather(){
                    this.isHot = !this.isHot
                }
            },
            // 监视写法一
            // watch:{

            //     // 完成写法
            //     // isHot:{
            //     //     // immediate:true,  // 该参数设置为true,可以在初始化的时候让handler调用一下     
            //     //     // deep:true,        // 深度监视
            //     //     // 属性变化的回调函数
            //     //     handler(newValue,oldValue){
            //     //         console.log('属性isHot被修改了',newValue,oldValue);
            //     //     },
            //     // },

            //     // 简写形式
            //     // 当我们监视的配置属性只有handler()函数,不需要设置deep和immediate时,可以采用简写形式
            //     isHot(newValue,oldValue){
            //         console.log('属性isHot被修改了',newValue,oldValue);
            //     }
            // }
        });

        // // 正常写法
        // vm.$watch('isHot',{
        //              // immediate:true,  // 该参数设置为true,可以在初始化的时候让handler调用一下     
        //             // deep:true,        // 深度监视
        //             // 属性变化的回调函数
        //             handler(newValue,oldValue){
        //                 console.log('属性isHot被修改了',newValue,oldValue);
        //             }
        // });

        // 简写形式
        vm.$watch('isHot',function(newValue,oldValue){
            console.log('属性isHot被修改了',newValue,oldValue);
        })
    </script>

三、计算属性VS监视属性

计算属性(computed)和监视属性(watch)之间的区别

       1. computed能完成的功能,watch都可以完成。

       2. watch能完成的功能,computed不一定能完成,例如:watch可以进行异步操作。

两个重要的小原则

       1. 所被Vue管理的函数,最好写成普通函数,这样this的指向才是vm 或 组件实例对象。

       2. 所有不被Vue所管理的函数(定时器的回调函数、ajax的回调函数等、Promise的回调函数),最好写成箭头函数,这样this的指向才是vm 或 组件实例对象。

计算属性示例:

new Vue({
    el:'#root', 
    data:{ 
        firstName:'张',
        lastName:'三'
    },
    computed:{
    	fullName(){
		    return this.firstName + '-' + this.lastName
    	}
    }
})

监视属性示例

new Vue({
  el:'#root',
  data:{
    firstName:'张',
    lastName:'三',
    fullName:'张-三'
  },
  watch:{
    firstName(val){
      setTimeout(()=>{
        this.fullName = val + '-' + this.lastName
      },1000);
    },
    lastName(val){
      this.fullName = this.firstName + '-' + val
    }
  }
})

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值