Vue02-计算属性+监视属性

 


Vue02-计算属性+监视属性

1.计算属性-使用插值表达式和methods实现和计算属性相同的效果

<body>
<div id="app">
    <input type="text" v-model="firstName"> <br><br>
    <input type="text" v-model="lastName"> <br><br>
    <!-- 1 插值表达式实现 -->
    <span>{{firstName}} - {{lastName}}</span> <br><br>
    <!-- 2 methods实现。使用methods,当firstName或者lastName变化后,都会触发模板重新解析,
        当模板重新解析时,就会调用fullName()。 -->
    <span>{{fullName()}}</span>
</div>

<script>
    const vm = new Vue({
        el: '#app',
        data: {
            firstName: '张',
            lastName: '三'
        },
        methods: {
            fullName() {
                console.log('fullName');
                return this.firstName + '=' + this.lastName;
            }
        }
    })
</script>
</body>

2.计算属性-计算属性简单使用

<body>

<div id="app">
    <input type="text" v-model="firstName"> <br><br>
    <input type="text" v-model="lastName"> <br><br>
    <!-- 1 计算属性。要使用的属性不存在,并且要使用的属性需要通过已有的属性计算得来。 -->
    <!-- 2 计算属性底层借助了Object.defineProperty()方法提供的get和set来完成。 -->
    <!-- 3 计算属性中get执行的事件。1 初始化读取时会执行一次;2 当所以依赖的数据发生变化时会被再次调用。 -->
    <!-- 4 计算属性和methods相比,计算属性内部有缓存机制,所以效率更好,而且方便vue调试。 -->
    <!-- 5 计算属性最终会被代理到vm上,可以直接使用。 -->
    <!-- 6 如果计算属性需要被修改,set可以返回计算属性修改后的值,但是set中必须有要使得依赖计算属性的数据发生变化的数据。 -->
    <span>{{fullName}}</span> <br><br>
    <!-- 第一次完成计算属性的初始化之后,就不会在执行fullName的get方法,
    因为第一次fullName在初始化时已经调用了get,所以第二次直接从缓存中去读fullName的值。 -->
    <span>{{fullName}}</span> <br><br>
    <span>{{fullName}}</span> <br><br>
</div>

<script>
    const vm = new Vue({
        el: '#app',
        data: {
            firstName: '张',
            lastName: '三'
        },
        computed: {
            // 计算属性的值需要是一个对象,对象中可以包含get和set。
            fullName: {
                get() {
                    // 计算属性对象中的this为Vue实例对象
                    console.log(this); // Vue实例对象
                    return this.firstName + '-' + this.lastName;
                },
                // 如果通过vm.fullName = 'a-b'修改计算属性,则必须提供set,否则报错。
                set(val) {
                    let arr = val.split('-');
                    this.firstName = arr[0];
                    this.lastName = arr[1];
                }
            }
        }
    })
</script>
</body>

3.计算属性-计算属性的简写

<body>

<div id="app">
    <input type="text" v-model="firstName"> <br><br>
    <input type="text" v-model="lastName"> <br><br>

    <span>{{fullName03}}</span> <br><br>
</div>

<script>
    const vm = new Vue({
        el: '#app',
        data: {
            firstName: '张',
            lastName: '三'
        },
        computed: {
            // 计算属性一般只用于页面数据展示,所以一般情况下只有get。
            fullName01: {
                get() {
                    return this.firstName + '-' + this.lastName;
                }
            },

            // 计算属性在只有get时可以简写为函数。
            fullName02: function () {
                return this.firstName + '-' + this.lastName;
            },

            // 计算属性简写为函数后,函数也可以在简写。
            fullName03() {
                return this.firstName + '-' + this.lastName;
            }
        }
    })
</script>
</body>

4.监视属性-天气切换案例

<body>

<div id="app">
    <!-- 通过插值语法中写简单的表达式来获取天气。 -->
    <p>天气{{isHot ? '炎热' : '凉爽'}}</p>
    <!-- 通过属性获取天气 -->
    <p>天气{{getWeather}}</p>
    <!-- 通过点击使用调用methods中的方法来切换天气。 -->
    <button @click="changeWeather">切换天气01</button>

    <!-- @xxx=yyy,yyy可以写一些简单的语句。通过点击事件修改data中的属性来修改添加。 -->
    <button @click="isHot = !isHot">切换天气02</button>
</div>

<script>
    const vm = new Vue({
        el: '#app',
        data: {
            isHot: true
        },
        methods: {
            changeWeather() {
                this.isHot = !this.isHot;
            }
        },
        computed: {
            getWeather() {
                return this.isHot ? '炎热' : '凉爽';
            }
        }
    })
</script>
</body>

5.监视属性-监视属性简单使用

<body>

<div id="app">
    <p>天气</p>
    <button @click="changeWeather">切换天气01</button>
</div>

<script>
    // 监视属性。
    // 1 当被监视属性变化时,自动回调handler函数,进行相关操作。
    // 2 监视属性必须存在,才能够监视。
    // 3 监视属性的两种写法。
    //      1 new Vue()时传入watch配置。
    //      2 通过vm.$watch()监视。
    const vm = new Vue({
        el: '#app',
        data: {
            isHot: true
        },
        methods: {
            changeWeather() {
                this.isHot = !this.isHot;
            }
        },
        // watch表示监视属性。
        watch: {
            // 监视isHot属性,值为一个配置对象。
            isHot: {
                // immediate默认为false,在监视属性初始化时不调用handler;
                // 当immediate为true时监视属性在初始化时就会调用一次handler。
                immediate: true,
                // handler在监视属性变化时会被调用。
                // handler在调用时会传入两个参数:所监视属性改变后的新值和所监视属性改变前的旧值。
                handler(newValue, oldValue) {
                    console.log(newValue, oldValue);
                }
            }
        }
    });

    // 4 监视属性的第二种写法,需要传入两个参数。
    // 第一个参数监视的属性;第二个参数为配置对象。
    vm.$watch('isWatch', {
        immediate: true,
        handler(newValue, oldValue) {
            console.log('监视属性的第二种写法');
        }
    })
</script>
</body>

6.监视属性-深度监视

<body>

<div id="app">
    <!-- 监视numbers内部属性a。 -->
    监视a <span>{{numbers.a}}</span>
    <button @click="numbers.a++">a+1</button> <br><br>

    <!-- 如果监视的numbers,numbers内部的值a改变了,numbers不会被监视到发生了改变。 -->
    监视numbers <span>{{numbers.a}}</span>
    <button @click="numbers.a++">a+1</button> <br><br>

    <!-- 如果监视的是numbers,只有当numbers的地址发生变化了,numbers的变化才会被监视到。 -->
    监视numbers地址 <span>{{numbers.a}}</span>
    <button @click="numbers = {a: 1, b: 1}">切换numbers地址</button> <br><br>

    <!-- 深度监视,当goods内部的任意值,发生了变化,numbers就会被监视到发生了变化。 -->
    <!--
        深度监视。
            1 Vue中watch默认不监视对象内部值发生改变。
            2 在watch中配置deep:true后可以监视到对象内部值发生改变。
            3 Vue自身其实可以监视的对象内部值发生了变化,但是Vue提供的watch默认不可以。
            4 使用watch时,需要根据对象具体的结构决定是否进行深度监视。
    -->
    监视goods.m <span>{{goods.m}}</span>
    <button @click="goods.m++">m+1</button> <br><br>
</div>

<script>
    const vm = new Vue({
        el: '#app',
        data: {
            numbers: {
                a: 1,
                b: 1
            },
            goods: {
                m: 1,
                n: 1
            }
        },
        watch: {
            // 监视numbers内部属性a。
            'numbers.a': {
                handler() {
                    console.log('a改变了');
                }
            },
            numbers: {
                handler() {
                    console.log('numbers改变了');
                }
            },
            // deep: true,表示进行深度监视。
            goods: {
                deep: true,
                handler() {
                    console.log('goods内部a改变了')
                }
            }
        }
    });
</script>
</body>

7.监视属性-监视属性简写

<body>

<div id="app">
    <button @click="isHot = !isHot">切换天气02</button>
</div>

<script>
    const vm = new Vue({
        el: '#app',
        data: {
            isHot: true,
            isFlag: true
        },
        watch: {
            // 当监视属性中没有其他配置属性时可以进行简写,如果有其他的配置项,
            // 如deep或者immediate,是不可以进行简写的。
            isHot(newValue, oldValue) {
                console.log(newValue, oldValue);
            }
        }
    });

    // 当使用vm.$watch()监视时的简写。同样监视中只有handler属性才可以进行简写。
    vm.$watch('isFlag', function (newValue, oldValue) {
        console.log(newValue, oldValue);
    })
</script>
</body>

8.监视属性-watch和computed比较

<body>

<div id="app">
    <!--
        监视属性和计算属性。
        1 computed可以完成的功能,watch都可以完成。
        2 watch可以完成的功能,computed不一定可以完成,如watch可以进行异步操作。
        3 被Vue所管理的函数,最好写成普通函数,这样this的指向才是vm或者组件实例对象。
        4 不被Vue所管理的函数(定时器的回调函数,ajax的回调函数),最好写成箭头函数,
            这样this的指向才是vm或者组件实例对象。
    -->
    <input type="text" v-model="firstName">
    <input type="text" v-model="lastName">
    <input type="text" v-model="age">
    <!-- 使用计算属性拼接姓名 -->
    <span>{{fullName}}</span> <br>

    <!-- 使用监视属性拼接姓名 -->
    <span>{{name}}</span>
    <span>{{age}}</span>
</div>
<script>
    const vm = new Vue({
        el: '#app',
        data: {
            firstName: '张',
            lastName: '三',
            name: '张三',
            age: '10'
        },
        computed: {
            fullName() {
                // 计算属性中无法进行异步延时调用。
                setTimeout(() => {
                    console.log('kkk');
                }, 1000);
                return this.firstName + '-' + this.lastName;
            }
        },
        watch: {
            firstName() {
                this.name = this.firstName + this.lastName;
            },
            lastName() {
                // 监视属性中可以进行异步延时调用。
                setTimeout(() => {
                    this.name = this.firstName + this.lastName;
                }, 1000);
            },
            age() {
                // vue监视属性中异步定时任务传入普通函数和箭头函数的区别。
                // 1 setTimeout()定时器所指定的回调函数由JavaScript引擎提调用。
                // 2 setTimeout()函数参数为普通函数时,普通函数内部this为window。
                // 3 setTimeout()函数参数为箭头函数时,this会向外寻找,所以this为Vue实例对象。
                setTimeout(function () {
                    console.log(this); // window
                    this.name = this.firstName + this.lastName;
                }, 1000);

                setTimeout(() => {
                    console.log(this); // Vue实例对象
                    this.name = this.firstName + this.lastName;
                }, 1000);
            }
        }
    });
</script>
</body>
posted @   行稳致远方  阅读(27)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
点击右上角即可分享
微信分享提示