Vue中计算属性和监视属性

计算属性

1.定义:要用的属性不存在,要通过已有的属性计算得来

2.原理:底层借助了Object.defineproperty方法提供的getter和setter

3.getter函数什么执行?

  (1)初次读取时会执行一次

  (2)当依赖的数据发生改变时会被再次调用

4.优势:与methods实现相比,内部有缓存机制(复用),效率更高,调试方便

5.备注:

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

  (2)如果计算属性要被修改,那必须写set函数去响应修改,且set中要引起计算时依赖的数据发生改变

<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>
<script type="text/javascript">
    Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。

    const vm = new Vue({
        el:'#root',
        data:{
            firstName:'',
            lastName:''
        },
        computed:{
            fullName:{
                //get有什么作用?当有人读取fullName时,get就会被调用,且返回值就作为fullName的值
                //get什么时候调用?1.初次读取fullName时。2.所依赖的数据发生变化时。
                get(){
                    console.log('get被调用了')
                    // console.log(this) //此处的this是vm
                    return this.firstName + '-' + this.lastName
                },
                //set什么时候调用? 当fullName被修改时。
                set(value){
                    console.log('set',value)
                    const arr = value.split('-')
                    this.firstName = arr[0]
                    this.lastName = arr[1]
                }
            }
       
        // 简写
        fullName(){
            return this.firstName + "-" + this.lastName
        }
        
        }
    })
</script>

 监视属性

1.当被监视的属性变化时,回调函数自动调用,进行相关操作

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

3.监视的两张方法:

  (1)new Vue时传入watch的配置

  (2)通过vm.$watch监视

<div id="root">
    <h2>今天天气很{{info}}</h2>
    <button @click="changeWeather">切换天气</button>
</div>
<script type="text/javascript">
    Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
    
    const vm = new Vue({
        el:'#root',
        data:{
            isHot:true,
        },
        computed:{
            info(){
                return this.isHot ? '炎热' : '凉爽'
            }
        },
        methods: {
            changeWeather(){
                this.isHot = !this.isHot
            }
        },
        /* watch:{
            isHot:{
                immediate:true, //初始化时让handler调用一下
                //handler什么时候调用?当isHot发生改变时。
                handler(newValue,oldValue){
                    console.log('isHot被修改了',newValue,oldValue)
                }
            }
        } */
    })

    vm.$watch('isHot',{
        immediate:true, //初始化时让handler调用一下
        //handler什么时候调用?当isHot发生改变时。
        handler(newValue,oldValue){
            console.log('isHot被修改了',newValue,oldValue)
        }
    })
</script>

 4.深度监视

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

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

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

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

<div id="root">
    <h2>今天天气很{{info}}</h2>
    <button @click="changeWeather">切换天气</button>
    <hr/>
    <h3>a的值是:{{numbers.a}}</h3>
    <button @click="numbers.a++">点我让a+1</button>
    <h3>b的值是:{{numbers.b}}</h3>
    <button @click="numbers.b++">点我让b+1</button>
    <button @click="numbers = {a:666,b:888}">彻底替换掉numbers</button>
    {{numbers.c.d.e}}
</div>

<script type="text/javascript">
    
    const vm = new Vue({
        el:'#root',
        data:{
            isHot:true,
            numbers:{
                a:1,
                b:1,
                c:{
                    d:{
                        e:100
                    }
                }
            }
        },
        computed:{
            info(){
                return this.isHot ? '炎热' : '凉爽'
            }
        },
        methods: {
            changeWeather(){
                this.isHot = !this.isHot
            }
        },
        watch:{
            /* isHot:{
                // immediate:true, //初始化时让handler调用一下
                //handler什么时候调用?当isHot发生改变时。
                handler(newValue,oldValue){
                    console.log('isHot被修改了',newValue,oldValue)
                }
            },*/
       // 简写
       isHot(newValue,oldValue) {
       console.log('isHot被修改了',newValue,oldValue,this)
}
//监视多级结构中某个属性的变化 /* 'numbers.a':{ handler(){ console.log('a被改变了') } } */ //监视多级结构中所有属性的变化 numbers:{ deep:true, handler(){ console.log('numbers改变了') } } } })

  
    //正常写法
      /* vm.$watch('isHot',{
            immediate:true, //初始化时让handler调用一下
            deep:true,//深度监视
            handler(newValue,oldValue){
                console.log('isHot被修改了',newValue,oldValue)
            }
       }) */

       //简写
       /* vm.$watch('isHot',(newValue,oldValue){
            console.log('isHot被修改了',newValue,oldValue,this)
       }) */
</script>

 

 

computed和watch之间的区别:

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

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

两个重要的小原则

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

2.不被vue所管理的函数(定时器的回调函数、ajax的回调函数等,Promise的回调函数)最好写成箭头函数

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

<script type="text/javascript">

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

 

posted @ 2023-12-24 14:16  喻聪  阅读(8)  评论(0编辑  收藏  举报