Vue中的computed(计算属性)可以为我们做点什么

计算属性

首先看一下官方是怎么介绍的

官网中的意思是复杂的表达式应该替换成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中,copmutedmethods写法上有些相似,但是还是有一些不同点。
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>

上述代码中直接引用发生变化是不会更新视图的,而computedwatch是可以的,具体原因大家可以去了解一下深拷贝和浅拷贝,值传递和引用传递。这个例子告诉我们对对象的监听是有两种方法的,并且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;

  • 3
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值