Vue.js系列之四计算属性和观察者

一、计算属性

1、模版内的表达式非常便利,但是设计它们的初衷是用于简单计算的。在模版中放入太多的逻辑运算会让模版过重且难以维护,例如如下代码:

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

在这个地方,模版不在是简单的声明式逻辑,你必须看一段时间才能意识到,这里是想要显示变量message的翻转字符串,当你想要在模版中多次引用此处的翻转字符串时,就会更加难以处理.

所以,任何复杂逻辑,你都应当使用计算属性,基础例子如下:

<body>
    <div id="currentPage">
        <p>Original message:"{{message }}"</p>
        <p>Computed reversed message:"{{reversedMessage }}"</p>
    </div>
</body>
<script type="text/javascript">
    var currPage=new Vue({
        el:"#currentPage",
        data:{
            message:"https://www.baidu.com"
        },
        computed:{
            reversedMessage:function () {
                return this.message.split('').reverse().join('')
            }
        }
    });
</script>

2、计算属性缓存vs方法

上面的功能通过方法也可以实现,但是通过方法和计算属性实现相同的功能是有区别的,虽然两种计算方式的最终结果完全相同。然而,不同的计算属性是基于它们的依赖进行缓存的.计算属性只有在相关依赖发生改变时才会重新求值。这意味着只要message没有发生改变,多次访问reversedMessage计算属性会立即返回之前的计算结果,而不必再次执行函数.这意味着下面的计算属性不再更新,因为Date.Now()不是响应式依赖,代码如下:

computed: {
  now: function () {
    return Date.now()
  }
}

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

3、计算属性为什么需要缓存

假设我们有一个性能开销比较大的计算属性A,它需要便利一个巨大的数组并作大量的计算,然后我们可能有其它的属性依赖A,如果没有缓存,我们将不可避免的多次执行A的getter!当然如果你不需要缓存,请用方法来替代.

4、计算属性Vs侦听属性

Vue提供了一种更通用的方式来观察和响应Vue实例上的数据变动:侦听属性。当你有一些数据需要随着其他属性的变动而变动时,很容易滥用watch,特别是使用过AngularJS,代码如下:

<body>
    <div id="pageIndex">
        <p>{{fullName}}</p>
    </div>
</body>
<script type="text/javascript">
    var currentPage=new Vue({
        el:"#pageIndex",
        data:{
            firstName:"Stepen",
            lastName:"Curry",
            fullName:"Stepen Curry"
        },
        watch:{
            firstName:function (val) {
                this.fullName=val+' '+this.lastName;
            },
            lastName:function (val) {
                this.fullName=this.firstName+' '+this.lastName;
            }
        }
    });
</script>

上面通过watch属性能很好的解决属性联动的问题,但是Vue提供了一种跟好的方式来解决这个问题,计算属性,代码如下:

<body>
    <div id="pageIndex">
        <p>{{fullName}}</p>
    </div>
</body>
<script type="text/javascript">
    var currentPage=new Vue({
        el:"#pageIndex",
        data:{
            firstName:"Stepthen",
            lastName:"Curry"
        },
        computed:{
            fullName:function(){
                return this.firstName+' '+this.lastName;
            }
        }
    });
</script>

比较两种属性联动的方法显然,计算属性相比watch要好得多.

5、计算属性的setter

计算属性在你不指定setter的时候,只有getter,当然有些时候我们可能会对计算属性进行特殊的处理,这个时候就需要使用setter,比如我们需要对上面例子中的fullName进行额外的处理,代码如下:

<body>
    <div id="pageIndex">
        <p>{{fullName}}</p>
    </div>
</body>
<script type="text/javascript">
    var currentPage=new Vue({
        el:"#pageIndex",
        data:{
            firstName:"Stepthen",
            lastName:"Curry"
        },
        computed:{
            fullName:{
                get:function(){
                    return this.firstName+' '+this.lastName;
                },
                set:function (newFullName) {
                    var names=newFullName.split(',');
                    this.firstName=names[0];
                    this.lastName=names[names.length-1];
                }
            }
        }
    });
</script>

当在控制台中运行currentPage.fullName='xiao,chao',set方法会被调用,currentPage.firstName和currentPage.lastName也会被相应地更新.

6、watch侦听器

虽然计算属性在大多数情况下更合适,但是有时需要一个自定义的侦听器,这就是为什么Vue通过watch选项提供了一个更通用的方法,来响应数据的变化。当需要数据变化时,执行异步或开销更大的操作时,这个方法是最有用的.

<body>
    <div id="pageIndex">
        <p>
            <input v-model="question" />
        </p>
        <p>{{answer}}</p>
    </div>
</body>
<script type="text/javascript">
    var currentPage=new Vue({
        el:"#pageIndex",
        data:{
            question:'',
            answer:'请在输入框输入你的问题!'
        },
        watch:{
            question:function (newQuestion) {
                this.answer='服务器正在处理你的问题,请稍候......';
                this.getAnswer();
            }
        },
        methods:{
            getAnswer:function () {
                //这里放ajax方法
                setTimeout(function () {
                    currentPage.answer='服务器返回的答案';
                },500);
            }
        }
    });
</script>

在这个示例中,使用watch选项允许我们执行一个异步操作(访问你个api),限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态.这些都是计算属性无法做到的.

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏影子

jQuery中的常用内容总结(三)

46590
来自专栏个人随笔

Java 面向对象三大特征之一:封装

面向对象三大特征之一:封装 概念: 将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法类实现对隐藏信息的操作和访问 封装的好处: 隐藏...

36470
来自专栏前端黑板报

Sass vs Less

2007年发布,最早的一款CSS预处理器,带来了变量、常量、嵌套、混入、函数、循环等功能, 解决了CSS不可编程的短板。由于浏览器不能直接识别Sass,所以需要...

23690
来自专栏互联网杂技

StackOverflow上关于JavsScript的热门问答

Q1:javascript的闭包是如何工作的? 正如爱因斯坦所说的: 如果你不能把它解释给一个六岁的小孩,说明你对它还不够了解。 我曾尝试向一个27岁的朋友解释...

33760
来自专栏醒者呆

掌握一门语言Go

摘要:Go语言的优势不必多说,通过本篇文章,让我们花时间来掌握一门外语,Let's Go! 关键字:Go语言,闭包,基本语法,函数与方法,指针,slic...

45890
来自专栏前端桃园

JavaScript ES6  让我们写得少,做得多

JavaScript ES6 带来了新的语法和新的强大功能,使您的代码更现代,更易读。它允许您编写更少的代码并执行更多操作。 ES6 向我们介绍了许多强大的功能...

11820
来自专栏听雨堂

Execute 方法(Find 对象)

Execute 方法(Find 对象) 运行指定的查找操作。如果查找成功,则返回 True。 语法 expression.Execute(FindText, M...

19970
来自专栏TungHsu

这或许是对小白最友好的python入门了吧——2,变量和字符串

长期以来,编程界都认为刚接触一门新语言时,如果首先使用它来编写一个在屏幕上显示消息 “Hello world!” 的程序,将给你带来好运。 因为微信排版编辑问题...

28450
来自专栏影子

jQuery中的常用内容总结(三)

11520
来自专栏腾讯NEXT学位

初探TypeScript

10020

扫码关注云+社区

领取腾讯云代金券