前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Vue.js系列之四计算属性和观察者

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

作者头像
郑小超.
发布2018-01-26 17:08:00
9390
发布2018-01-26 17:08:00
举报
文章被收录于专栏:GreenLeavesGreenLeaves

一、计算属性

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

代码语言:javascript
复制
<div id="example">
  {{ message.split('').reverse().join('') }}
</div>

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

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

代码语言:javascript
复制
<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()不是响应式依赖,代码如下:

代码语言:javascript
复制
computed: {
  now: function () {
    return Date.now()
  }
}

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

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

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

4、计算属性Vs侦听属性

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

代码语言:javascript
复制
<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提供了一种跟好的方式来解决这个问题,计算属性,代码如下:

代码语言:javascript
复制
<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进行额外的处理,代码如下:

代码语言:javascript
复制
<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选项提供了一个更通用的方法,来响应数据的变化。当需要数据变化时,执行异步或开销更大的操作时,这个方法是最有用的.

代码语言:javascript
复制
<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),限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态.这些都是计算属性无法做到的.

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-11-17 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档