vue——计算属性、监视属性

86 篇文章 0 订阅
73 篇文章 0 订阅

计算属性

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

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

3.get原理函数什么时候执行?

​ 3.1初次读取该时会执行一次

​ 3.2当依赖的数据发生改变时会被再次调用

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

5.备注:

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

​ 5.2如果计算属性要被修改,那必须写set函数去响应修改,且set中要引起计算时依赖的数据

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../js/vue.js"></script>
</head>

<body>
    <div id="root">
        <input type="text" v-model="firstName"><br/>
        <input type="text" v-model="lastName">
        <p>全名:{{name}}</p>
    </div>
    <script>
        const vm = new Vue({
            el: "#root",
            data: {
                firstName: "张",
                lastName: "三"
            },
            // 计算属性,对data中的属性做进一步的加工处理再输出(输出的是一个对象),会有缓存
            computed: {
                /* get调用name? 1.初次读取nane时;2.所依赖的数据发生变化时 */
                name: {
                    //    get何时被调用? 1.初次读取nane时;2.所依赖的数据发生变化时
                    get() {
                        console.log("get被调用了");
                        return this.firstName.slice() + "-" + this.lastName;
                    },
                    // name被修改时调用set
                    set(value) {
                        // console.log(value);
                        console.log("set修改");
                        // 将字符串按指定的字符分割成数组
                        const arr = value.split('-');
                        this.firstName = arr[0];
                        this.lastName = arr[1]
                    }
                },
                // 简写法:将name写成一个函数形式
                /* name() {
                    return this.firstName.slice() + "-" + this.lastName;
                } */
            }
        })
    </script>
</body>

</html>

监视属性

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

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

3.监视的两种写法:

​ 3.1在new Vue({})里面使用watch配置

​ 3.2通过vm.$watch监视

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../js/vue.js"></script>
</head>

<body>
    <div id="root">
        <!-- <h1>今天天气{{w?"炎热":"凉爽"}}</h1> -->
        <h1>今天天气{{weather}}</h1>
        <!-- <button @click="fnc">切换天气</button> -->
        <!-- 事件绑定的等号后面不止可以写函数名也可以写一些简单的语句 -->
        <button @click="w=!w">切换天气</button>
    </div>
    <script>
        // 如果明确了要监视那个属性,就用watch,如果开始不知道监视谁,后续有需要监视的,就用.$watch()
        const vm = new Vue({
            el: "#root",
            data: {
                w: true
            },
            methods: {
                /* fnc() {
                    this.w = !this.w
                } */
            },
            computed: {
                // 完整-配置对象
                /* weather: {
                    get() {},
                    set() {}
                }, */
                // 函数形式
                weather() {
                    return this.w ? "炎热" : "凉爽"
                }
            },
            // 监视1.0
            /*  watch: {
                 // 监视的对象
                 weather: {
                     // immediate:初始化时立即执行handler,默认是false
                     immediate: true,
                     // 当w发生改变时会调用handler回调函数
                     handler(newVal, oldVal) {
                         // console.log(newVal);
                         // console.log(oldVal);
                         console.log("今天天气 " + newVal + ",昨天天气 " + oldVal);
                     }
                 }
             } */
        });
        // 监视2.0,首先是要先创建一个Vue实例对象
        // $watch(x,y):第一个参数是要监视的对象,第二个参数是配置对象
        vm.$watch("weather", {
            immediate: true,
            handler(newVal, oldVal) {
                console.log("今天天气 " + newVal + ",昨天天气 " + oldVal);
            }
        })
    </script>
</body>

</html>
深度监视

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

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

备注:

1.vue自身可以监测对象内部值得改变,但是vue提供的watch默认不可以

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

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../js/vue.js"></script>
</head>

<body>
    <div id="root">
        <h1>今天天气{{weather}}</h1>
        <button @click="w=!w">切换天气</button>
        <hr>
        <h3>a:{{number.a}}</h3>
        <button @click="number.a++">a++</button>
        <hr>
        <h3>b:{{number.b}}</h3>
        <button @click="number.b++">b++</button>
    </div>
    <script>
        const vm = new Vue({
            el: "#root",
            data: {
                w: true,
                number: {
                    a: 1,
                    b: 0
                }
            },
            methods: {},
            computed: {
                weather() {
                    return this.w ? "炎热" : "凉爽"
                }
            },
            // vue默认是可以监测到data中多层级的数据改变的,但是vue为程序员提供的watch默认是不可以监测多层级数据的
            // 想要在vue提供的watch里面监测到多层级数据的改变的,就要添加deep: true,
            watch: {
                // 原始写法
                // "xxx":{},
                weather: {
                    immediate: true,
                    handler(newVal, oldVal) {
                        console.log("今天天气 " + newVal + ",昨天天气 " + oldVal);
                    }
                },
                // 监视多级结构中的某个属性的变化需要用原始写法(外面加引号)
                /* "number.a": {
                    handler() {
                        console.log("number里面的a数据改变了");
                    }
                }, */
                number: {
                    // 监视多级结构中的所有属性的变化
                    deep: true,
                    handler() {
                        console.log("number里面的数据改变了");
                    }
                }
            }
        });
    </script>
</body>

</html>

监视属性的简写

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../js/vue.js"></script>
</head>

<body>
    <div id="root">
        <h1>今天天气{{weather}}</h1>
        <button @click="w=!w">切换天气</button>
    </div>
    <script>
        const vm = new Vue({
            el: "#root",
            data: {
                w: true,
            },
            methods: {},
            computed: {
                weather() {
                    return this.w ? "炎热" : "凉爽"
                }
            },
            watch: {
                // 原始写法
                // "xxx":{},
                // 正常写法
                /*  weather: {
                     // immediate: true,
                     // deep: true,
                     handler(newVal, oldVal) {
                         console.log("今天天气 " + newVal + ",昨天天气 " + oldVal);
                     },
                 } */
                // 简写形式:只有handler而已,没有其他的配置项,这里的weather就相当于handler
                /* weather(newVal, oldVal) {
                    console.log("今天天气 " + newVal + ",昨天天气 " + oldVal);
                } */
            }
        });
        // 正常写法
        /* vm.$watch('weather', {
            immediate: true,
            deep: true,
            handler(newVal, oldVal) {
                console.log("今天天气 " + newVal + ",昨天天气 " + oldVal);
            }
        }) */
        // 简写:只有回调函数,没有其他的配置项
        vm.$watch('weather',
            function(newVal, oldVal) {
                console.log("今天天气 " + newVal + ",昨天天气 " + oldVal);
            })
    </script>
</body>

</html>
计算属性和监视属性的区别

计算属性是对data中的数据进行加工后形成新的数据,并且输出;data中的数据发生改变,形成的那个新数据也会发生响应的改变

监视属性是监测到data中的某个属性发生变化时,会进行特定的一些处理,不需要输出

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

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

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

​ 2.1所有不被vue所管理的函数(定时器的回调函数、ajax的回调函数、promise的回调函数等),最好写成箭头函数,这样this的指向才是vue的实例对象或者组件实例

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../js/vue.js"></script>
</head>

<body>
    <div id="root">
        <input type="text" v-model="firstName"><br/>
        <input type="text" v-model="lastName">
        <p>全名:{{name}}</p>
    </div>
    <script>
        new Vue({
            el: "#root",
            data: {
                firstName: "张",
                lastName: "三",
                name: '张-三'
            },
            // 监视属性可以执行异步代码,而计算属性不可以
            watch: {

                // 监视姓:姓发生改变,将改变后的姓的新值与名拼接,组成新的姓名
                firstName(newVal) {
                    // 在这里用的是箭头函数,
                    setTimeout(() => {
                        this.name = newVal + "-" + this.lastName
                    }, 1000)
                },
                // 监视名:名发生变化,将名的新值与姓拼接,组成新的姓名
                lastName(newVal) {
                    this.name = this.firstName + "-" + newVal
                    setTimeout(function() {}, 1000)
                }
            }
        })
    </script>
</body>

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值