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),限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态.这些都是计算属性无法做到的.
- 分析Silverlight跨域调用
- Spring集成RabbiMQ-Spring AMQP新特性
- Nodejs学习笔记(二)--- 事件模块
- 巧用FireFox来调试Silverlight
- Nodejs学习笔记(一)--- 简介及安装Node.js开发环境
- WCF后续之旅(7):通过WCF Extension实现和Enterprise Library Unity Container的集成
- 区块链技术(一):Truffle开发入门
- Nodejs学习笔记(一)——初识Nodejs
- RabbitMQ入门-Topic模式
- 单分子数据储存取得一大突破,一枚“硬币”存量相当于100部iPhone 7
- Windows 7 旗舰版 VHD安装体验
- Nodejs学习笔记(二)——Eclipse中运行调试Nodejs
- Nodejs学习笔记(三)——一张图看懂Nodejs建站
- 不规则图形的碰撞检测
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 基于Btrace的监控调试
- 大数据框架—Flink与Beam
- Mybatis动态SQL
- Mybatis-Generator插件的使用与Spring集成Mybatis的配置
- Mybatis的缓存机制详解
- zookeeper基本特性与基于Linux的ZK客户端命令行学习
- Apache Curator操作zookeeper的API使用
- 使用Java API操作zookeeper的acl权限
- 使用ZooKeeper提供的原生Java API操作ZooKeeper节点
- CountDownLatch类的使用
- Spring-如何给静态变量注入值
- ZooKeeper的伪分布式集群搭建以及真分布式集群搭建
- zookeeper权限acl与四字命令
- 微信公众号开发-素材/消息管理接口
- 微信开发的一些神坑