04-计算属性

李先生 2020年12月13日 87次浏览

计算属性

什么是计算属性

  • 我们知道,在模版中可以通过插值语法显示一些data中的数据。
  • 但是在某些情况,我们可能需要对数据进行一些转化后再显示
    • 比如我们有firstname和lastName两个变量,我们需要显示完整的名称
    • 但是如果多个地方都需要显示完整的名称,我们就需要写多个{{firstName}} {{lastName}}
  • 我们可以将上面的代码转换成计算属性:
    • 计算属性是写在实例的computed选项中的。
<!DOCTYPE html>

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

<body>
    <div id="app">
        <h2>{{firstName+" "+lastName}}</h2>
        <h2>{{firstName}} {{lastName}}</h2>
        <h2>{{getFullName()}}</h2>
        <h2>{{fullName}}</h2>
    </div>
    <script>
        const app = new Vue({
           el:'#app',
           data:{
               firstName:'Lebron',
               lastName:'James'
           },
        //    计算属性
           computed:{
               fullName:function(){
                   return this.firstName + " " + this.lastName
               }
           },
           methods:{
               getFullName(){
                   return this.firstName + " " + this.lastName
               }
           }
        });
    </script>
</body>

</html>

计算属性的复杂操作

  • 计算属性中也可以进行一些更加复杂的操作,比如下面的例子:
<!DOCTYPE html>

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

<body>
    <div id="app">
        <h2>总价格:{{totalPrice}}</h2>
    </div>
    <script>
        const app = new Vue({
           el:'#app',
           data:{
               books:[
                   {id:110,name:'Unix编程艺术',price:119},
                   {id:111,name:'代码大全',price:105},
                   {id:112,name:'深入理解计算机原理',price:98},
                   {id:113,name:'现代操作系统',price:87},

               ]
           },
           // 多次调用只计算一次  有缓存  比methods性能高
           computed:{
               totalPrice:function(){
                   // 常用高阶函数filter/map/reduce 
                   let result = 0
                //    for (let i=0;i<this.books.length;i++){
                //        result+=this.books[i].price
                //    }
                //    for(let i in this.books){
                //        result+=this.books[i].price
                //    }
                   for(let i of this.books){
                       result += i.price
                   }
                   return result
               }
           },
           methods:{}
        });
    </script>
</body>

</html>

计算属性的setter和getter

  • 每个计算属性都包含一个getter和setter
    • 在上面的例子中,我们只是使用getter来读取
    • 在某些情况下,你也可以提供一个setter方法(不常用)
    • 在需要写setter的时候,代码如下:
<!DOCTYPE html>

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

<body>
    <div id="app">
        <h2>{{fullName}}</h2>
        <h2>{{firstName}}</h2>
        <h2>{{lastName}}</h2>
    </div>
    <script>
        const app = new Vue({
           el:'#app',
           data:{
               firstName:'Lebron',
               lastName:'James'
           },
        //    计算属性
           computed:{
               // 但是计算属性一般是没有set方法的,这时这个属性就是一个只读属性
               fullName:{
                   get(){
                       console.log('调用了fullName的getter')
                       return this.firstName + " " + this.lastName
                   },
                   set(newValue){
                       console.log('调用了fullName的setter')
                       const names = newValue.split(' ')
                       this.firstName = names[0]
                       this.lastName = names[1]
                   }
               }
           },
           methods:{
               getFullName(){
                   return this.firstName + " " + this.lastName
               }
           }
        });
    </script>
</body>

</html>

计算属性computed跟methods的对比

  • methods每次被使用都会重新执行一次函数,一般用于需要动态处理展示的数据
  • computed多次使用时,只会调用一次函数,因为vue会对它进行缓存,只有当他的值发生改变时,才会再次调用函数,当被处理的数据需要进行很多for循环时,该方法效率会高很多
<!DOCTYPE html>

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

<body>
    <div id="app">
        <!-- 1.直接拼接,语法过于繁琐 -->
        <h2>{{firstName + " " + lastName}}</h2>
        <!-- 2.通过methods 每次使用都需要调用一次,当处理函数有for循环时
            效率会很低
        -->
        <h2>{{getFullName()}}</h2>
        <h2>{{getFullName()}}</h2>
        <h2>{{getFullName()}}</h2>
        <h2>{{getFullName()}}</h2>
        <!-- 3.通过computed 多次使用只需要调用一次,vue会对结果进行缓存
            当检测到值发生变化时才会再次调用
            效率高
        -->
        <h2>{{fullName}}</h2>
        <h2>{{fullName}}</h2>
        <h2>{{fullName}}</h2>
        <h2>{{fullName}}</h2>
    </div>
    <script>
        const app = new Vue({
           el:'#app',
           data:{
                firstName:'Lebron',
                lastName:'James'
           },
           methods:{
               getFullName : function(){
                   console.log("getFullName被调用");
                   return this.firstName + ' ' + this.lastName
               }
           },
           computed:{
               fullName: function(){
                console.log("fullName被调用");
                   return this.firstName + ' ' + this.lastName
               }
           }
        });
    </script>
</body>

</html>

计算属性的缓存

  • 我们可能会考虑这样的一个问题:
    • methods和computed看起来都可以实现我们的功能
    • 那为什么还要多一个计算属性这个东西?
    • 原因:计算属性会进行缓存,如果多次使用时,计算属性只会调用一次