04-Vue计算属性与监视

在这里插入图片描述

前言

📋前言📋
💝博客:【无聊大侠hello word】💝
✍有一点思考,有一点想法,有一点理性!✍
✍本文由在下【无聊大侠hello word】原创,首发于CSDN✍

传统方式做运算

方式1:直接在插值表达式里面做运算

<div id="app">
       姓:<input type="text" v-model="firstName"> 
       <br>
       名:<input type="text" v-model="lastName">
       <br>
       全名:<span>{{firstName.slice(0,3)}}-{{lastName}}</span>
    </div>
</body>
<script>
    Vue.config.productionTip = false;
    const vm = new Vue({
        el: '#app',
        data: {
            firstName: '张',
            lastName: '三'
        }
    });
</script>

Vue不推荐在插值表达式里加入过多的运算逻辑。

方式2:计算逻辑配置成method,然后将method配置到插值表达式位置调用

<body>
    <div>
        methods实现
    </div>
    <div id="app">
       姓:<input type="text" v-model="firstName"> 
       <br>
       名:<input type="text" v-model="lastName">
       <br>
        <!-- 在插值表达式里调用method -->
       全名:<span>{{fullName()}}</span>
       <br>
    </div>
</body>
<script>
    Vue.config.productionTip = false;
    const vm = new Vue({
        el: '#app',
        data: {
            firstName: '张',
            lastName: '三'
        },
        methods: {
            fullName() {
                // 因为method的this和data的this都是指的Vue实例vm,所以此处可以获取到vm的firstName、lastName
                return this.firstName + "-" + this.lastName;
            }
        },
    });
</script>

计算属性

<body>
    <div>
        计算属性实现
    </div>
    <div id="app">
       姓:<input type="text" v-model="firstName"> 
       <br>
       名:<input type="text" v-model="lastName">
       <br>
       全名:<span>{{fullName}}</span>
       <br>
       第二次读取全名:<span>{{fullName}}</span>
       <br>
    </div>
</body>
<script>
    Vue.config.productionTip = false;
    const vm = new Vue({
        el: '#app',
        data: {
            firstName: '张',
            lastName: '三'
        },
        // 计算属性`在这里插入代码片`
        computed: {
            fullName: {
                get() { // 计算属性需要有个getter,在该方法中编写计算逻辑
                    console.log('fullName被读取了');
                    console.log(this);  // 此处的this是vm
                    return this.firstName + "-" + this.lastName;
                }
            }
        }
    });
</script>

计算属性是计算出来的,在vm._data中不存在。

计算属性在通过getter获取完值之后会缓存下来,如果内容不变,下次再读取时将不再进行计算。但是当其依赖的变量发生变化时,计算属性的getter会再次被调用。

计算属性如果只是为了读取,那么只编写getter即可。但是如果需要修改计算属性,那么还需要编写setter:

(一般情况下,计算属性是计算完用来读取的,很少有修改计算属性的)

const vm = new Vue({
        el: '#app',
        data: {
            firstName: '张',
            lastName: '三'
        },
        // 计算属性
        computed: {
            fullName: {
                get() {
                    console.log('fullName被读取了');
                    console.log(this);  // 此处的this是vm
                    return this.firstName + "-" + this.lastName;
                },
                
                // setter非必须,只有fullName会被修改时才需要该方法
                set(value) {
                    console.log('setter方法执行了:' + value);
                }
            }
        }
    });

当计算属性只有getter时,可以进行简写:

computed: {
    // fullName属性只有getter,可以直接简写成fullName(),表示就是该属性的getter
    fullName() {
        console.log('fullName被读取了');
        console.log(this);  // 此处的this是vm
        return this.firstName + "-" + this.lastName;
    }
}

监视属性(侦听属性)

  1. 通过vm对象的$watch()watch配置来监视指定的属性

  2. 当属性变化时,回调函数自动调用,在函数内部进行计算

@click等事件绑定方法可以直接编写一些简单的实现:

<body>
    <div id="app">
       <button @click="changeWeather">切换天气</button>
    </div>
</body>
<script>
    Vue.config.productionTip = false;
    const vm = new Vue({
        el: '#app',
        data: {
            isHot: true
        },
        methods: {
            changeWeather() {
                this.isHot = !this.isHot;
            }
        },
    })
</script>

可以简写为:

<!-- 直接在绑定事件上编写简单的语句 -->
<button @click="isHot = !isHot">切换天气</button>

此时,如果想监控isHot属性的修改,可以使用watch配置监视:

const vm = new Vue({
    el: '#app',
    data: {
        isHot: true
    },
    
    // .......
    
    // 配置监视
    watch: {
        isHot: {  // 要监视的属性
            handler(newValue, oldValue) {  // 当isHot发生改变时被调用
                console.log(`isHot改变了,从${oldValue}变成了${newValue}`);
            }
        }
    }
})

其他配置项:

// 配置监视
watch: {
    isHot: {  // 要监视的属性
        handler(newValue, oldValue) {  // 当isHot发生改变时被调用
            console.log(`isHot改变了,从${oldValue}${newValue}`);
        },
        immediate: true  // 页面打开就直接先执行一次handler方法,默认false
    }
}

计算属性也是可以被watch监测的。

通过vm也可以配置监视:

const vm = new Vue({
    el: '#app',
    data: {
        isHot: true
    },
    computed: {
        weather() {
            return this.isHot ? "炎热" : "凉爽"
        }
    },
    methods: {
        changeWeather() {
            this.isHot = !this.isHot;
        }
    }
});

// 通过vm的$watch方法进行监视
// 参数1,要监视的属性
// 参数2,配置项
vm.$watch('isHot', {
    handler(newValue, oldValue) {  // 当isHot发生改变时被调用
        console.log(`isHot改变了,从${oldValue}${newValue}`);
    },
    immediate: true
});

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

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

vm.$watch()方式监视的属性不存在时不报错

监视多级结构中某个属性的变化:

const vm = new Vue({
        el: '#app',
        data: {
            isHot: true,
            numbers: {
                a: 1,
                b: 1
            }
        },
        watch: {
           // 监视多级结构中某个属性的变化
            'numbers.a': {  // 监视 numbers里面的a属性的变化
                handler(newValue, oldValue) {
                    console.log('a被改变了')
                }
            }
        }
    });

监视对象的里面的属性变化:

const vm = new Vue({
    el: '#app',
    data: {
        isHot: true,
        numbers: {
            a: 1,
            b: 1
        }
    },
    // 配置监视
    watch: {
        numbers: {
            handler() {
                console.log('numbers改变了');
            },
            // 开启深度监视,默认false
            // 如果不开启深度监视,只有numbers这个对象本身变化了才能监视到。numbers里面的a、b属性值变化无法检测到
            // 开启了深度监视后,numbers里面的属性值变化也可以被监视到
            deep:true
        }
    }
});

监视属性简写:

当配置项里只有handler()时,就可以使用简写形式

watch: {
    isHot(newValue, oldValue) {
        console.log(`isHot改变了,从${oldValue}${newValue}`);
    }
}

计算属性和监视属性对比

监视属性可以开启异步。

例如:

监视属性可以使用以下写法:

const vm = new Vue({
    el: '#app',
    data: {
        firstName:'张',
        lastName:'三',
        fullName:'张-三'
    },
    watch: {
        firstName(newValue) {
            // firstName修改后,延迟1秒再修改fullName的值
            setTimeout(() => {
                this.fullName = newValue + "-" + this.lastName; 
            }, 1000);                
        }
    }
});

计算属性因为是return,所以不能开启异步:

 const vm = new Vue({
     el: '#app',
     data: {
         firstName: '张',
         lastName: '三'
     },
     computed: {
         fullName: {
             get() {
                 // 此处这么写是错误的,运行不出来的
                 // 此处的return 会将返回值返回给setTimeout的回调函数,不能返回给get
                 setTimeout(() => {
                     return this.firstName + "-" + this.lastName;
                 }, 1000);                    
             }
         }
     }
 });

还需要注意的是:在监视属性中,使用setTimeout延迟时,里面的回调函数必须写成箭头函数的形式:

因为setTimeout里面的回调函数不是VUE管理的函数,而是js引擎管理的。所以如果里面不写成箭头函数,那么里面的回调函数的this就将指向window。里面的回调函数写成箭头函数后,箭头函数没有this,向外找的时候就会找到vue实例的this。

总结:

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


不是vue管理的函数(例如定时器的回调函数、ajax的回调函数、promise的回调函数),最好写成箭头函数,这样this指向的才是vm或组件实例对象。

先赞后看,养成习惯!!!^ _ ^ ❤️ ❤️ ❤️
码字不易,大家的支持就是我的坚持下去的动力。点赞后不要忘了关注我哦!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值