6.计算属性

未匹配的标注
  • 本系列文章为laracasts.com 的系列视频教程——Learn Vue 2: Step By Step 的学习笔记。若喜欢该系列视频,可去该网站订阅后下载该系列视频,支持正版
  • 视频源码地址:github.com/laracasts/Vue-Forms
  • 项目初始版本为Vue 2.1.3,教程还在更新中。

本节说明

  • 对应第 6 小节:The Need For Computed Properties

本节内容

本节我们来学习 计算属性 。首先,我们需要了解,在Vue中,数据绑定最常见的形式就是使用“Mustache”语法 (双大括号) 的文本插值:

<h2>Message: {{ message }}</h2>

Mustache 标签将会被替代为对应数据对象上message属性的值。无论何时,绑定的数据对象上message属性发生了改变,插值处的内容都会更新。并且,对于所有的数据绑定,Vue.js 都提供了完全JavaScript表达式支持。比如,如果我们想将message的内容倒序输出:

<!DOCTYPE html>

<html>
    <head>

    </head>

    <body>
        <div id="root">
            <h2>{{ message.split('').reverse().join('') }}</h2>
        </div>

        <script src="https://unpkg.com/vue@2.1.3/dist/vue.js"></script>

        <script>
            var app = new Vue({
                el:'#root',

                data: {
                    message:'Hello World',
                }
            });
        </script>
    </body>
</html>

查看效果:
file
模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的。在模板中放入太多的逻辑会让模板过重且难以维护。在上面这个例子中,模板不再是简单的声明式逻辑。你必须看一段时间才能意识到,这里是想要显示变量message的翻转字符串。当你想要在模板中多次引用此处的翻转字符串时,就会更加难以处理。

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

.
.
<body>
    <div id="root">
        <h2>{{ reverseMessage }}</h2>
    </div>

    <script src="https://unpkg.com/vue@2.1.3/dist/vue.js"></script>

    <script>
        var app = new Vue({
            el:'#root',

            data: {
                message:'Hello World',
            },

            computed:{
                reverseMessage() {
                    return this.message.split('').reverse().join('');
                }
            }
        });
    </script>
</body>
    .
    .

你可以像绑定普通属性一样在模板中绑定计算属性。Vue 知道app.reversMessage依赖于app.message,因此当app.message发生改变时,所有依赖app.reversMessage的绑定也会更新。如下:
file
你可能已经想到,我们可以将同一函数定义为一个方法而不是一个计算属性。两种方式的最终结果确实是完全相同的:

<body>
    <div id="root">
        <h2>{{ reverseMessage() }}</h2>
    </div>

    <script src="https://unpkg.com/vue@2.1.3/dist/vue.js"></script>

    <script>
        var app = new Vue({
            el:'#root',

            data: {
                message:'Hello World',
            },

            methods:{
                reverseMessage() {
                    return this.message.split('').reverse().join('');
                }
            }
        });
    </script>
</body>

然而,不同的是,计算属性是基于它们的依赖进行缓存的 。只在相关依赖发生改变时它们才会重新求值。这就意味着只要message还没有发生改变,多次访问计算reversMessage属性会立即返回之前的计算结果,而不必再次执行函数。

相比之下,每当触发重新渲染时,调用方法将总会再次执行函数

我们为什么需要缓存?假设我们有一个性能开销比较大的计算属性 A,它需要遍历一个巨大的数组并做大量的计算。然后我们可能有其他的计算属性依赖于 A 。如果没有缓存,我们将不可避免的多次执行 A 的 getter 函数。如果你不希望有缓存,可以用方法来替代。

下面我们来看下一个例子:我们有一个任务清单,分别展示了所有任务,已完成任务,未完成任务。如下:

<body>
    <div id="root">
        <h2>All Tasks</h2>
        <ul>
            <li v-for="task in tasks" v-text="task.description"></li>
        </ul>

        <h2>Completed Tasks</h2>
        <ul>
            <li v-for="task in tasks" v-if="task.completed"v-text="task.description"></li>
        </ul>

        <h2>Incompleted Tasks</h2>
        <ul>
            <li v-for="task in incompletedTasks" v-text="task.description"></li>
        </ul>
    </div>

    <script src="https://unpkg.com/vue@2.1.3/dist/vue.js"></script>

    <script>
        var app = new Vue({
            el:'#root',

            data: {
                tasks:[
                    {description:'Go to the store',completed:false},
                    {description:'Make dinner',completed:true},
                    {description:'Clean room',completed:false}
                ]
            },

            computed:{
                incompletedTasks() {
                    return this.tasks.filter(task => ! task.completed);
                }
            }
        });
    </script>
</body>

我们分别使用计算属性来展示未完成任务。现在我们有一个小练习:在每一项未完成任务清单后面加上一个按钮,点击按钮完成任务。加油吧,下一节我们继续前进。

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 0
发起讨论 只看当前版本


暂无话题~