Vue语法--计算属性

简介: Vue语法--计算属性

一. 计算属性



1. 什么是计算属性?


通常, 我们是在模板中, 通过插值语法显示data的内容, 但有时候我们可能需要在{{}}里添加一些计算, 然后在展示出来数据. 这时我们可以使用到计算属性


先来举个例子, 比如: 一个班, 有几个学生参加期末考试, 要计算考试的平均分. 我们来看看, 通常要怎么做?

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">考试成绩
    <ul>
        <li v-for="stu in students">{{stu.name}} -- {{stu.score}}</li>
    </ul>
    <p>平均分: <label>{{getAvg()}}</label></p>
</div>
<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: "#app",
        data: {
            message:"班级考试平均分",
            students: [
                {name:"张三", score:90},
                {name:"lisi", score:100},
                {name:"wangwu", score:99},
                {name:"zhaoliu", score:89},
                {name:"liuqi", score:95}
            ]
        },
        methods: {
            getAvg() {
                let sum = 0;
                 for (let i = 0; i < this.students.length; i++) {
                     console.log(this.students[i].score);
                     let stu = this.students[i];
                     sum += stu.score;
                 }
                 console.log("平均分:" + sum/this.students.length);
                 return sum/this.students.length;
            }
        }
    })
</script>
</body>
</html>

我们定义了一组学生的成绩. 然后将其显示在页面上, 然后通过方法getAvg计算平均分.


1187916-20210220063957352-1765421474.png

 

这里我们在获取平均分的时候, 使用的是{{getAve()}} 其实, 平均分我们理解更像是一个属性, 而不是一个方法. 为了方便计算, vue给我们提供了一个computed属性, 专门用来做计算. computed中定义的也是方法, 这个方法的方法名通常都定义为名词. 我们来看一下使用

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">考试成绩
    <ul>
        <li v-for="stu in students">{{stu.name}} -- {{stu.score}}</li>
    </ul>
    <p>平均分: <label>{{avg}}</label></p>
</div>
<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: "#app",
        data: {
            message:"班级考试平均分",
            students: [
                {name:"zhangsan", score:90},
                {name:"lisi", score:100},
                {name:"wangwu", score:99},
                {name:"zhaoliu", score:89},
                {name:"liuqi", score:95}
            ]
        },
        computed: {
            avg: function() {
                let sum = 0;
                for (let i = 0; i < this.students.length; i++) {
                    console.log(this.students[i].score);
                    let stu = this.students[i];
                    sum += stu.score;
                }
                console.log("平均分:" + sum/this.students.length);
                return sum/this.students.length;
            }
        },
        methods: {
        }
    })
</script>
</body>
</html>

这里,增加了一个computed属性, 里面定义了avg方法, 没错, 本质还是方法, 但命名的时候, 将其命名为名词.


眼尖的同学应该已经发现了, 这好像和methods方法一样啊, 就是换了个名字. 那computed计算属性和methods方法有什么区别呢?


2. 计算属性computed的缓存功能


我们用案例来说明他们之间的区别.


案例1. methods方法

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <p> Origin Message: {{message}}</p>
    <p>Mthod Message:{{getMessage()}}</p>
    <p>Mthod Grade:{{getGrade()}}</p>
    <p>Mthod Class:{{getClass()}}</p>
</div>
<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: "#app",
        data: {
            message:"班级考试平均分",
            className: "1班",
            gradeName:"一年级"
        },
        methods: {
            getGrade: function(){
                console.log("调用Grade计算")
                return "方法" + this.gradeName
            },
            getClass: function(){
                console.log("调用class计算")
                return "方法" + this.className
            },
            getMessage: function(){
                console.log("调用message计算")
                return "方法" + this.message
            }
        }
    })
</script>
</body>
</html>

1187916-20210220071318140-1474777228.png

我们发现, 在修改一个属性, 其他属性都没变化的情况下, 我们发现methods里的方法都被执行了一遍


案例2. computed计算属性

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <p> Origin Message: {{message}}</p>
    <p>Mthod Message:{{getMessage}}</p>
    <p>Mthod Grade:{{getGrade}}</p>
    <p>Mthod Class:{{getClass}}</p>
</div>
<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: "#app",
        data: {
            message:"班级考试平均分",
            className: "1班",
            gradeName:"一年级"
        },
        computed: {
            getGrade: function(){
                console.log("调用Grade计算")
                return "方法" + this.gradeName
            },
            getClass: function(){
                console.log("调用class计算")
                return "方法" + this.className
            },
            getMessage: function(){
                console.log("调用message计算")
                return "方法" + this.message
            }
        }
    })
</script>
</body>
</html>

控制台输出



我们发现, 当控制台修改其中一个属性值, 只有调用这个属性的方法会重新执行

 

案例3:  再看一个computed缓存的例子


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <p>调用方法</p>
    <p>{{getMes()}}</p>
    <p>{{getMes()}}</p>
    <p>{{getMes()}}</p>
    <p>{{getMes()}}</p>
    <p>调用计算属性</p>
    <p>{{mes}}</p>
    <p>{{mes}}</p>
    <p>{{mes}}</p>
    <p>{{mes}}</p>
</div>
<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: "#app",
        data: {
            firstName: "Elon",
            lastName: "Musk"
        },
        computed: {
            mes: function(){
                console.log("调用计算属性")
                return this.firstName + " " + this.lastName
            }
        },
        methods: {
            getMes: function(){
                console.log("调用method方法")
                return  this.firstName  + " " +  this.lastName
            }
        }
    })
</script>
</body>
</html>


这是两种方式的调用, 但是结果都一样, 都是打印输出姓名, 计算属性mes调用了四次, 方法getMes()也调用了四次, 我们来看看运行结果

1187916-20210220071016457-373127418.png

两次打印的结果是一样的, 但是调用getMes()调用了4次, 而mes计算属性只计算了一次.

 

总结



  • methods方法和computed计算属性,两种方式的最终结果确实是完全相同
  • 不同的是计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值,多次访问getMessage 计算属性会立即返回之前的计算结果,而不必再次执行函数。
  • methods方法,每当触发重新渲染时,调用方法将总会再次执行函数。

所以,官网说,对于任何复杂逻辑,都应当使用计算属性。


3. 计算属性的getter和setter访问器


问题: 我们发现, 在计算属性和methods方法调用的是偶还有一点不同, 那就是调用方式不同. method方调用是{{getMessage()}}, 而计算属性是{{getMessage}}, 我们上面不是说计算属性中定义的也是方法么? 为什么不需要使用()呢? 下面来研究一下

还是这个案例, 我们来看看代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">{{message}} {{avg}}</div>
<script src="../js/vue.js"></script>
<script>
    var app = new Vue({
        el: "#app",
        data: {
            message: "计算平均分:",
            students: [
                {name:"zhangsan", score:90},
                {name:"lisi", score:100},
                {name:"wangwu", score:99},
                {name:"zhaoliu", score:89},
                {name:"liuqi", score:95}
            ]
        },
        computed: {
            avg: function() {
                let sum = 0;
                for (let i = 0; i < this.students.length; i++) {
                    console.log(this.students[i].score);
                    let stu = this.students[i];
                    sum += stu.score;
                }
                console.log("平均分:" + sum/this.students.length);
                return sum/this.students.length;
            }
        }
    });
</script>
</body>
</html>

我们在计算平均分的时候, 是把avg当做一个属性来对待的, 所以,调用的时候这么写{{avg}}, 而不是{{avg()}}. 但是我们定义的时候却是给定义成方法了, 为什么会这样呢?

下面我们来研究computed完整的写法, 研究完这个, 就知道为什么这么写了.

 

  • 其实计算属性本身是定义为了一个属性. 例如: 我们定义test, 通常我们定义属性是这么定义的


test: "这是一个属性"

  • 在计算属性里, 属性值是一个对象, 所以, 我们要这么定义
computed: {
    test: {
    }
}


  • 对象的内部有两个方法, 一个是get方法, 一个是set方法. 这时在get方法中return一个abc, 这是, 在页面显示的就应该是abc
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">{{message}} --- {{avg}} --- {{test}}</div>
<script src="../js/vue.js"></script>
<script>
    var app = new Vue({
        el: "#app",
        data: {
            message: "计算平均分:",
            students: [
                {name:"zhangsan", score:90},
                {name:"lisi", score:100},
                {name:"wangwu", score:99},
                {name:"zhaoliu", score:89},
                {name:"liuqi", score:95}
            ]
        },
        computed: {
            avg: function() {
                let sum = 0;
                for (let i = 0; i < this.students.length; i++) {
                    console.log(this.students[i].score);
                    let stu = this.students[i];
                    sum += stu.score;
                }
                console.log("平均分:" + sum/this.students.length);
                return sum/this.students.length;
            },
            test : {
                set: function(newValue) {
                    this.message = newValue;
                    console.log("调用setter")
                },
                get: function() {
                    return "abc" 
                }
            }
        }
    });
</script>
</body>
</html>

看看效果

1187916-20210220123217831-920015448.png


确实打印输出了abc

 

 

  • 因为有get方法和set方法, 所以, 我们可以修改test的值,  如下: 修改了app.test的值, 最终改变了message的值.

 1187916-20210220124806013-1511628019.png

  • 然而, 计算属性通常只实现get方法, 而不实现set方法. 我们是计算后输出, 而不允许北外不修改,  这时计算属性就只剩下一个get方法, 最后我们将其简写, 去掉get, 就是我们通常看到的写法
computed: {
    avg: function() {
        let sum = 0;
        for (let i = 0; i < this.students.length; i++) {
            console.log(this.students[i].score);
            let stu = this.students[i];
            sum += stu.score;
        }
        console.log("平均分:" + sum/this.students.length);
        return sum/this.students.length;
    },
    avg1 : function() {
            return "abc" 
    }
}


虽然写法和method差不多. 但本质上, 计算属性还是属性, 所以, 和属性的写法是一样的.

相关文章
|
9天前
|
移动开发 JavaScript API
Vue Router 核心原理
Vue Router 是 Vue.js 的官方路由管理器,用于实现单页面应用(SPA)的路由功能。其核心原理包括路由配置、监听浏览器事件和组件渲染等。通过定义路径与组件的映射关系,Vue Router 将用户访问的路径与对应的组件关联,支持哈希和历史模式监听 URL 变化,确保页面导航时正确渲染组件。
|
13天前
|
监控 JavaScript 前端开发
ry-vue-flowable-xg:震撼来袭!这款基于 Vue 和 Flowable 的企业级工程项目管理项目,你绝不能错过
基于 Vue 和 Flowable 的企业级工程项目管理平台,免费开源且高度定制化。它覆盖投标管理、进度控制、财务核算等全流程需求,提供流程设计、部署、监控和任务管理等功能,适用于企业办公、生产制造、金融服务等多个场景,助力企业提升效率与竞争力。
68 12
|
9天前
|
JavaScript 前端开发 开发者
Vue中的class和style绑定
在 Vue 中,class 和 style 绑定是基于数据驱动视图的强大功能。通过 class 绑定,可以动态更新元素的 class 属性,支持对象和数组语法,适用于普通元素和组件。style 绑定则允许以对象或数组形式动态设置内联样式,Vue 会根据数据变化自动更新 DOM。
|
9天前
|
JavaScript 前端开发 数据安全/隐私保护
Vue Router 简介
Vue Router 是 Vue.js 官方的路由管理库,用于构建单页面应用(SPA)。它将不同页面映射到对应组件,支持嵌套路由、路由参数和导航守卫等功能,简化复杂前端应用的开发。主要特性包括路由映射、嵌套路由、路由参数、导航守卫和路由懒加载,提升性能和开发效率。安装命令:`npm install vue-router`。
|
2月前
|
JavaScript
vue使用iconfont图标
vue使用iconfont图标
152 1
|
30天前
|
JavaScript 安全 API
iframe嵌入页面实现免登录思路(以vue为例)
通过上述步骤,可以在Vue.js项目中通过 `iframe`实现不同应用间的免登录功能。利用Token传递和消息传递机制,可以确保安全、高效地在主应用和子应用间共享登录状态。这种方法在实际项目中具有广泛的应用前景,能够显著提升用户体验。
70 8
|
1月前
|
存储 设计模式 JavaScript
Vue 组件化开发:构建高质量应用的核心
本文深入探讨了 Vue.js 组件化开发的核心概念与最佳实践。
77 1
|
3月前
|
JavaScript 前端开发 开发者
vue 数据驱动视图
总之,Vue 数据驱动视图是一种先进的理念和技术,它为前端开发带来了巨大的便利和优势。通过理解和应用这一特性,开发者能够构建出更加动态、高效、用户体验良好的前端应用。在不断发展的前端领域中,数据驱动视图将继续发挥重要作用,推动着应用界面的不断创新和进化。
111 58
|
2月前
|
JavaScript 关系型数据库 MySQL
基于VUE的校园二手交易平台系统设计与实现毕业设计论文模板
基于Vue的校园二手交易平台是一款专为校园用户设计的在线交易系统,提供简洁高效、安全可靠的二手商品买卖环境。平台利用Vue框架的响应式数据绑定和组件化特性,实现用户友好的界面,方便商品浏览、发布与管理。该系统采用Node.js、MySQL及B/S架构,确保稳定性和多功能模块设计,涵盖管理员和用户功能模块,促进物品循环使用,降低开销,提升环保意识,助力绿色校园文化建设。
|
3月前
|
JavaScript 前端开发 开发者
vue学习第一章
欢迎来到我的博客!我是瑞雨溪,一名热爱前端的大一学生,专注于JavaScript与Vue,正向全栈进发。博客分享Vue学习心得、命令式与声明式编程对比、列表展示及计数器案例等。关注我,持续更新中!🎉🎉🎉
68 1
vue学习第一章

热门文章

最新文章