计算属性computed作用是通过一系列的方法得到新的属性及属性值。使用场景:当你需要一个数据,但是这个数据你目前没有,并且可以从目前已有的数据中计算得出。
监视属性watch类似一个“监控器”,可以指定“监视的对象”,而这个对象一定是已经存在的属性(因为不可能去监视一个不存在的事物),如果监视的对象发生改变,watch就要进行相对的操作(怎么进行操作?下面会解释)。使用场景:当你需要根据一个或者多个数据的值是否发生变化来决定要不要实行某些操作时。
补充:通常可以用computed的场合都可以使用watch去解决,但能用watch解决的computed不一定能解决。
举个简单的例子来看看computed和watch是如何使用的
<div id="root">
第一个数是:<input type="text" v-model="a">
第二个数是:<input type="text" v-model="b">
<!-- 方法调用 -->
<p>他们的和是:{{add()}}</p>
<!-- 计算属性 -->
<p>他们的和是:{{addNumber}}</p>
<!-- watch属性 -->
<p>更改a之后,他们的和是:{{sum}}</p></p></p>
</div>
<script src="./js/vue.js"></script>
<script>
new Vue({
el:'#root',
data(){
return {
a:10,
b:20,
sum:''
};
},
methods: {
add(){
return parseInt(this.a) + parseInt(this.b)
}
},
computed:{
//addNumber是vm实例对象上的一个新属性,不用写在data中
addNumber:{
// get方法的目的是:返回addNumber属性的值
get(){
return parseInt(this.a) + parseInt(this.b)
},
// 没有用到set方法,先不管
set(val){
newData = val;
}
}
},
watch:{
//a是被监视的数据(watch规定监视的数据一定是存在的,而且是可以变化的)
a:{
//当监视的数据发生改变时,会自动调用handler回调
handler(newVal,oldVal){
this.sum = parseInt(newVal) + parseInt(this.b)
}
},
}
})
</script>
从上面的代码块中,可以清晰看待computed和watch的使用位置和使用方法,这里就不再废话了。
computed属性的响应依赖机制,即目标数据发生变化时,才重新计算新属性值。从这一特性,可以知道computed一定存在缓存,因此效率也会提高,只要目标数据不发生变化,不管使用多少次computed属性,其中的get方法只调用一次。而method中的方法调用,是使用了几次方法调用,那么对应的方法就要被调用几次。
下面讲一下 Object.defineProperty
为什么要讲它呢,其实它是实现computed属性的基础
Object.defineProperty这个方法的功能是为对象添加或修改属性,其属性为响应式属性
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Document</title>
</head>
<body>
<script>
let obj = {
school:'zjnu',
student:'yr'
}
//三个参数:对象名,属性名,方法(包括两个,一个是get(),一个是set())
Object.defineProperty(obj,'msg',{
//get()方法的作用:得到msg属性的属性值
get(){
return this.school + '-' + this.student
},
//set()方法的作用:如果msg属性被重新赋值,我需要进行哪些操作,当然也可以不进行任何操作,根据需求来
set(val){
let arr = val.split('-')
this.school = arr[0]
this.student = arr[1]
}
})
console.log(obj.msg) //打印的结果:zjnu-yr
obj.msg = 'zjnu-messi'
console.log(obj) //打印的结果:{school: 'zjnu', student: 'messi'}这个对象的详细信息
</script>
</body>
</html>
其实我们经常能看见computed属性中并没有出现get和set,这是因为大多数情况下set()方法不常用,只使用get()方法,这个情况下就可以使用简写形式:
computed:{
//addNumber是vm实例对象上的一个新属性,不用写在data中
addNumber:{
return parseInt(this.a) + parseInt(this.b)
}
},
猫咪届的两种脸型