Vue笔记 - 计算属性(computed)和监视属性(watch)

计算属性和监视属性

1. 计算属性

  • 定义:使用的属性起初并不存在,要通过已有属性计算得来,这样的属性称作计算属性。

    • 计算属性以对象形式定义,需要在内部配置get和set方法
      • get函数会在初次读取时执行一次,当依赖的数据发生改变时会被再次调用
      • set函数会在计算属性被修改时执行。如果计算属性要被修改,那必须写set函数去响应修改,且set中要引起计算时依赖的数据发生(如果之后确定不需要修改计算属性,可以省略set)
  • 原理:底层借助了Object.defineproperty方法提供的getter和setter

  • 与methods实现相比,内部有缓存机制以供复用,效率更高,调试方便

    计算属性最终会出现在vm上,直接读取使用即可

    <div id="root">
        <h2>今天天气很{{info}}</h2>
        <button @click="changeWeather">切换天气</button>
    </div>
    
    <div id="root">
          姓: <input type="text" v-model="firstName"> <br/><br/>
          名: <input type="text" v-model="lastName"> <br/><br/>
          全名: <span>{{fullName}}</span>
    </div>
      
    <script>
    	new Vue({
            el:'#root',
            data:{
                firstName:'张',
                lastName:'三'
            },
            computed:{
                fullName:{
                    get(){
                        //此处this指向vm
                        return this.firstName + '-' + this.lastName;
                    },
                    set(value){
                        const arr = value.split('-')
                        this.firstName = arr[0]
                        this.lastName = arr[1]
                    }
                }
            }
        })
    </script>
    
  • 简写形式

    由于计算属性一般不需要获取,所以可以不设置setter函数,那么可以直接用属性名作为函数名

    computed:{
    	fullName(){
    		return this.firstName + '-' this.lastName
    	}
    }
    

2. 监视属性

  • 定义:如果需要监控数据的变动,可以设置监视属性。当被监视的属性变化时,回调函数自动调用,进行相关操作

  • 监视的属性必须存在,才能进行监视

  • 监视的两种写法:

    • new Vue时传入watch配置(适用于已确定的需要监视的属性)
    • 通过vm.$watch监视(适用于动态设置需要监视的属性)
    <div id="root">
        <h2>今天天气很{{info}}</h2>
        <button @click="changeWeather">切换天气</button>
    </div>
    
    <script>
    	new Vue({
            el:'#root',
            data:{
                isHot:true
            },
            method{
            	changeWeather(){
            		this.isHot = !this.isHot
        		}
        	},
            computed:{
                info(){
                    return this.isHot ? '炎热' : '凉爽'
                }
            },
            watch:{
                //当isHot属性被改变,调用回调函数handler
                'isHot':{
                    immediate:true, //初始化时让handler调用一次,默认为false
                    handler(newVal,oldVal){
                        console.log('isHot被修改',newVal,oldVal)
                    }
                }
            }
        })
    
        /*
        写法二:
        vm.$watch('isHot',{
            immediate:true, 
            handler(newVal,oldVal){
            	console.log('isHot被修改',newVal,oldVal)
            }
        })
        */
    </script>
    

2.1 深度监视

  • Vue中的watch默认不监测对象内部值的改变(一层)

    配置deep:true可以监测对象内部值改变(多层)

  • Vue自身可以监测对象内部值的改变,但Vue提供的watch默认不可以

    使用watch时根据数据的具体结构,决定是否使用深度监视

    <script>
    	new Vue({
            el:'#root',
            data:{
                numbers:{
                    a:1,
                    b:1
                }
            },
            watch:{
                'numbers':{
                    deep:true,
                    handler(){
                        console.log('numbers改变了')
                    }
                }
            }
        })
    </script>
    
  • 简写形式

    如果不需要对监视属性做额外配置(如immediate,deep)则可以直接简写

    watch:{
    	isHot()(newValue,oldValue){
    		console.log('isHot被修改了',newValue,oldValue)
    	}
    }
    

3. computed和watch对比

  • computed能完成的功能,watch都能完成

    watch能完成的功能,computed不一定能完成(如异步操作)

    但介于computed比watch方便得多,所以优先使用computed

  • 在异步操作中computed和watch的区别

    需求:将属性延迟1秒显示在页面上

    • watch:可以正常实现需求,因为watch不依赖return,而是直接修改数据
    watch:{
        firstName(val){
            setTimeout(() => {
                this.fullName = val + '-' + this.lastName
            },1000)
        }
    }
    
    • computed:无法实现需求,因为computed依赖return来返回数据,而异步操作无法实现这点
    computed:{
        firstName(){
            setTimeout(() => {
                //这样只会return到setTimeout函数里去
                return this.fullName + '-' + this.lastName
            },1000)
        }
    }
    
posted @   Solitary-Rhyme  阅读(126)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示