vue2学习笔记10 - 计算属性,方法和监视属性对比

需求:字符串转换成大写后合并

1、插值实现

直接在需要展示结果的地方,使用js表达式str.toUpperCase()然后拼接在一起。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>计算属性_插值</title>
        <!--引入vue.js,则全局就会多了一个vue的构造函数-->
        <script type="text/javascript" src="../js/vue.js"></script>
    </head>
    <body>
        <!--准备一个容器-->
        <div id="root">            
            字符串1:<input type="text" v-model="str1"><br/>
            字符串2:<input type="text" v-model="str2"><br/>
            <!--1、插值实现方式:缺点:模板中的表达式太长,不够精简-->
            转换成大写字母并合并:<span>{{str1.toUpperCase()}} {{str2.toUpperCase()}}</span>
        </div>
        <script type="text/javascript" >
            Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示
            const vm = new Vue({
                el:'#root',         
                data:{              
                    str1:'Hello',
                    str2:'World'
                }                
            })       
                        
        </script>
    </body>
</html>

缺点是模板中的表达式太长,不够精简,不符合官网【风格指南】中的强烈推荐【模板中简单的表达式】:组件模板应该只包含简单的表达式,复杂的表达式则应该重构为计算属性或方法。 

2、计算属性实现

模板中直接使用计算属性:

有get,那么就可能有对应的set:

//当fullString被修改时调用set
set(value){
     console.log("computed中的set被调用");
     const arr = value.toLowerCase().split(" ");
     this.str1 = arr[0];
     this.str2 = arr[1];
} 

 3、method实现

模板中调用方法:

4、监视属性实现

watch: {
   //当监测到str1改变时,计算
   str1: function (val) {
        this.fullname = val.toUpperCase() + ' ' + this.str2.toUpperCase()
   },
        //当检测到str2改变时,计算
   str2: function (val) {
        this.fullname = this.str1.toUpperCase() + ' ' + val.toUpperCase()
}

代码冗余。 

5、对比一下计算属性和method

乍一看,似乎二者都可以实现所需功能,但是,我们在模板中分别使用两次,观察一下console中的信息。

<!--2、计算属性实现方式:-->
【计算属性】转换成大写字母并合并:<span>{{fullString}}</span><br>
【计算属性】转换成大写字母并合并:<span>{{fullString}}</span><br>
<hr>
<!--3、method实现方式:缺点:效率不高-->
【methods】转换成大写字母并合并: <span>{{handleString()}}</span><br>
【methods】转换成大写字母并合并: <span>{{handleString()}}</span>

console中:虽然二者都被使用2次,但是计算属性中的get仅被调用一次,而method被调用了2次。这是因为计算属性有缓存机制,当它所依赖的属性发生变化时,它才会重新计算,否则,使用缓存值。这就使得它的执行效率比methods要高。 

 

6、计算属性的简写方式

如果非常确定计算属性仅用于展示,而不会被修改,那么可以不写setter,使用简写方式仅用于标识getter:

//如果确定该值仅用于展示,不会被修改,则可以不用写setter,那么getter也可以不写,如下:
fullString(){
   console.log("computed中的get被调用");
   return this.str1.toUpperCase() +" "+ this.str2.toUpperCase();
}

总结

  • 当要用的属性不存在,要通过已有的属性计算得来时,可使用计算属性。它借助了Object.defineproperty方法提供的getter/setter来实现双向绑定。其中,getter函数在初始化的时候会读取一次,在其依赖的属性发生改变时会再次调用。
  • 若其依赖属性未发生改变,代码中多次使用该属性,不会重复调用getter,而是读取其缓存值。
  • 虽然使用methods也可以实现所需要的功能,但是methods对其结果不具备缓存机制,每次调用,不论其依赖的属性是否发生变化,均会重新计算,因此,computed与methods相比,缓存机制的存在使得代码的执行效率更高。
  • 不过,计算属性如果可能会被修改,那么一定要自己写set函数来响应用户变更。
  • 如果确定计算属性仅用于展示,不会被修改,那么可以使用简写形式。
  • 监视属性:每次只能检测一个属性的变化。如果一个值需要依赖于多个属性,那么使用监视属性则会出现重复代码,这时使用计算属性更加合适。

本练习的全部代码:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>计算属性-方法-监视属性对比</title>
        <!--引入vue.js,则全局就会多了一个vue的构造函数-->
        <script type="text/javascript" src="../js/vue.js"></script>
    </head>
    <body>
        <!--准备一个容器-->
        <div id="root">            
            字符串1:<input type="text" v-model="str1"><br/>
            字符串2:<input type="text" v-model="str2"><br/>
            <!--1、插值实现方式:缺点:模板中的表达式太长,不够精简-->
            【插值方式】转换成大写字母并合并:<span>{{str1.toUpperCase()}} {{str2.toUpperCase()}}</span><br>
            <hr>
            <!--2、计算属性实现方式:-->
            【计算属性】转换成大写字母并合并:<span>{{fullString}}</span><br>
            【计算属性】转换成大写字母并合并:<span>{{fullString}}</span><br>
            <hr>
            <!--3、method实现方式:缺点:效率不高-->
            【methods】转换成大写字母并合并: <span>{{handleString()}}</span><br>
            【methods】转换成大写字母并合并: <span>{{handleString()}}</span>
            <hr>
            <!--4、watch实现方式:缺点:代码冗余-->
            【watch】转换成大写字母并合并: <span>{{fullname}}</span><br>            
        </div>
        <script type="text/javascript" >
            Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示
            const vm = new Vue({
                el:'#root',         
                data:{              
                    str1:'Hello',
                    str2:'World',
                    fullname:'Hello World'
                },
                
            computed: {
                //计算属性的完整写法
                /* fullString:{
                    get(){
                        console.log("computed中的get被调用");
                        return this.str1.toUpperCase() +" "+ this.str2.toUpperCase();
                    },
                    //当fullString被修改时调用set
                    set(value){
                        console.log("computed中的set被调用");
                        const arr = value.toLowerCase().split(" ");
                        this.str1 = arr[0];
                        this.str2 = arr[1];
                    } 
                } */

                //计算属性的简写:如果确定该值仅用于展示,不会被修改,则可以不用写setter,那么getter也可以不写,如下:
                fullString(){
                    console.log("computed中的get被调用");
                        return this.str1.toUpperCase() +" "+ this.str2.toUpperCase();
                }
            },  
                               
            methods: {
                handleString(){
                    console.log("调用methods中的方法")
                    return this.str1.toUpperCase() +" "+ this.str2.toUpperCase();
                }
            },
            
            watch: {
                //当监测到str1改变时,计算
                str1: function (val) {
                    this.fullname = val.toUpperCase() + ' ' + this.str2.toUpperCase()
                },
                //当检测到str2改变时,计算
                str2: function (val) {
                    this.fullname = this.str1.toUpperCase() + ' ' + val.toUpperCase()
                }
  }
        })       
                        
        </script>
    </body>
</html>

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值