Vue中的computed(计算属性)可以为我们做点什么
计算属性首先看一下官方是怎么介绍的官网中的意思是复杂的表达式应该替换成computed<template><div><p class="cla">{{text.split('').reverse().join('')}}</p><p class="cla">{{textReverse}}</p>&l...
计算属性
首先看一下官方是怎么介绍的
官网中的意思是复杂的表达式应该替换成computed
<template>
<div>
<p class="cla">{{text.split('').reverse().join('')}}</p>
<p class="cla">{{textReverse}}</p>
</div>
</template>
<script>
export default {
data () {
return {
text:'123456789'
}
},
computed:{
textReverse () {
return this.text.split('').reverse().join('')
}
}
}
</script>
在Vue中,computed
中使用到的data里的变量是可以追踪到的,当text
发生了改变时,textReverse
也会做出相应的改变。
textReverse () {
return this.text.split('').reverse().join('') + Date.now()
}
上诉中,因为 Date.now()
不是响应式依赖,通俗点就是Vue并没有对他去做追踪,所以当 Date.now()
发生了改变时视图不会变化的,而当text
发生了概念是会更新视图,相应的 Date.now()
也会取最新的值。
计算属性vs方法
Vue中,copmuted
和methods
写法上有些相似,但是还是有一些不同点。
1.计算属性是有一个返回值的,且必须有,返回值是一个差值表达式,而函数是不需要的,有没有返回值或者返回值是什么类型没有限制。(返回值方面)
2.用法上,在某些情况下是可以用方法代替计算属性的,比如某个不需要监听的值,而当值会变化并且视图需要随着值得变化去更新的话就不能用方法。(视图更新方面)
3.在写上也有些不同方法必须后面带()并且可以传参,而计算属性是不用调用的,直接用且不能传参。(写法方面)
4.计算属性是有缓存的。(性能方面)
计算属性 vs 侦听属性
Vue 提供了一种更通用的方式来观察和响应 Vue 实例上的数据变动:侦听属性。当你有一些数据需要随着其它数据变动而变动时,你很容易滥用 watch——特别是如果你之前使用过 AngularJS。
计算属性对比侦听属性(watch)来说,前者更像是一个方法,后者更像是一个命令。性能方面计算属性会更好一点,例如:
<template>
<div>
<p class="cla">{{text.split('').reverse().join('')}}</p>
<p class="cla">{{textReverse}}</p>
<p class="cla">{{textR}}</p>
</div>
</template>
<script>
export default {
data () {
return {
text:'123456789',
textR:''
}
},
computed:{
textReverse () {
return this.text.split('').reverse().join('')
}
},
watch:{
text (n,o) {
this.textR = n.split('').reverse().join('')
}
}
}
</script>
conputed
看起来更加好一点,但是,watch
就毫无用处了吗,官方给出了解释
虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器。这就是为什么 Vue 通过 watch 选项提供了一个更通用的方法,来响应数据的变化。当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。
计算属性的用法
目前版本的Vue中是不支持对象的双向绑定的,举个例子:
<template>
<div>
<p class="cla">{{data.content.text.split('').reverse().join('')}}</p>
<p class="cla">{{textReverse}}</p>
<p class="cla">{{textR}}</p>
</div>
</template>
<script>
export default {
props:['data'],
data () {
return {
// text:'123456789',
textR:''
}
},
computed:{
textReverse () {
return this.data.content.text.split('').reverse().join('')
}
},
watch:{
'data.content.text' (n,o) {
this.textR = n.split('').reverse().join('')
}
}
}
</script>
上述代码中直接引用发生变化是不会更新视图的,而computed
和watch
是可以的,具体原因大家可以去了解一下深拷贝和浅拷贝,值传递和引用传递。这个例子告诉我们对对象的监听是有两种方法的,并且computed
的性能会更好一点。
当然,Vue3.0事已经解决了这个问题,可以不做处理了
今天又翻到了之前的代码,给大家做一个对比,一个简单的倒计时功能:
jq版本的代码,当然还可以做优化,懒得改了
/*
<div class="settime">
<i>距团购结束</i>
<span>
<span></span>天
<span></span>小时
<span></span>分
<span></span>秒
</span>
</div>
第一个参数 div下的span节点
第二个参数过期时间
*/
class Settime{
constructor(parents,outtime){
this.parents = parents;
this.outtime = outtime;
this.count_down();
setInterval(function(){
that.count_down();
},1000)
}
count_down(){
var [now,tar]= [new Date().getTime(),Date.parse(this.outtime)];
var x = tar - now
var d = parseInt(x/(1000*3600*24));
var h = parseInt((x - d*(1000*3600*24))/(1000*3600))
var m = parseInt((x - d*(1000*3600*24) - h*(1000*3600))/(1000*60));
var s = parseInt((x - d*(1000*3600*24) - h*(1000*3600)-m*1000*60)/(1000));
d = (d<10)?"0"+d:d;
h = (h<10)?"0"+h:h;
m = (m<10)?"0"+m:m;
s = (s<10)?"0"+s:s;
var size = this.parents.children("span").size();
for(var i = 0;i<size;i+=4){
this.parents.children("span:eq("+i+")").html(d);
this.parents.children("span:eq("+(i+1)+")").html(h);
this.parents.children("span:eq("+(i+2)+")").html(m);
this.parents.children("span:eq("+(i+3)+")").html(s);
}
}
}
//new Settime($(".settime>span"),"2018/6/18 8:0:0");
export default Settime;
Vue版本的
<template>
<div class="span-box">
<span>{{countDown.h}}</span> :
<span>{{countDown.m}}</span> :
<span>{{countDown.s}}</span>
</div>
</template>
<script>
export default {
data () {
return {
num:0,
timer:null,
text:''
}
},
computed: {
countDown () {
let obj = {}
obj.h = (''+Math.floor(this.num/3600)).padStart(2, '0')
obj.m = (''+Math.floor(this.num%3600/60)).padStart(2, '0')
obj.s = (''+Math.floor(this.num%3600%60)).padStart(2, '0')
return obj
}
},
methods: {
// 倒计时
getCountDown (start_time,end_time) {
let timed = new Date(start_time).getTime() || Date.now();
let newtime = new Date(end_time).getTime();
this.num = Math.floor((timed - newtime ) / 1000);
this.timer = setInterval (()=>{
this.num--
if (this.num<=0) {
this.num = 0;
this.timer = null
if (this.changeFn) this.changeFn()//倒计时为0的时候更改状态方法
}
},1000)
},
}
}
</script>
显然Vue版本的会更简单一点,还可以不用computed去写,这样可能会麻烦一点。有兴趣的可以尝试一下
更多文章大家可以关注一下:
https://l-sui.github.io/欢迎大家来star,fork;
更多推荐
所有评论(0)