computed、method和watch都是vue中非常重要也是非常常用的几个API。他们三者之间有什么区别呢?首先我们来对比一下computed和method,下面来看一个案例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<script src="https://unpkg.com/vue@next"></script>
<div id="app">
<div>{{fristName + lastName}}</div>
<div>{{getFullName()}}</div>
<div>{{getFullName()}}</div>
<div>{{getFullName()}}</div>
</div>
<script>
Vue.createApp({
data() {
return {
fristName: 'John',
lastName: 'Doe',
}
},
methods: {
getFullName() {
return `${this.fristName} ${this.lastName}`
},
},
}).mount('#app')
</script>
</body>
</html>
我们尝试将fullName渲染出来,一种是直接将fristName与lastName拼接,另一种方法是使用method返回以一个方法将两者拼接。虽然是同样的效果,显然第二种方法更有封装性。那么这样是最好的解决方案吗?并不是。在这个案例上,method有两个缺点。第一fullName明明是一个属性值,而我们却使用调函数的方法来返回它,这不是非常的合适。第二如果我们要多次使用fullName时,那么method将会调用多次,这会造成性能的浪费。
所以我们可以使用我们的computed计算属性来完成这个案例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<script src="https://unpkg.com/vue@next"></script>
<div id="app">
<div>{{fristName + lastName}}</div>
<div>{{ fullName }}</div>
<div>{{ fullName }}</div>
<div>{{ fullName }}</div>
<div>{{getFullName()}}</div>
<div>{{getFullName()}}</div>
<div>{{getFullName()}}</div>
</div>
<script>
Vue.createApp({
data() {
return {
fristName: 'John',
lastName: 'Doe',
}
},
methods: {
getFullName() {
console.log(`methods中的fullName`)
return `${this.fristName} ${this.lastName}`
},
},
computed: {
fullName() {
console.log(`computed中的fullName`)
return `${this.fristName} ${this.lastName}`
},
},
}).mount('#app')
</script>
</body>
</html>
computed就很好地解决了这个问题。如图计算属性fullName调用了多次而只打印了一次,具有缓存特性,且并不需要使用括号调用,更符合编程习惯。实际上上图的代码computed只是一个语法糖,他的完整写法是含有getter和setter的一个对象。
computed: {
fullName: {
get(){
console.log(`computed中的fullName`)
return `${this.fristName} ${this.lastName}`
},
set(newValue){
console.log(`computed中的fullName`)
const names = newValue.split(' ')
this.fristName = names[0]
this.lastName = names[1]
}
}
},