您现在的位置是:首页 >技术杂谈 >Vue之使用Compition API生成计算属性computed网站首页技术杂谈
Vue之使用Compition API生成计算属性computed
概述
作为程序员我们都知道写代码不仅要高效完成需求,还要让我们的代码优雅、可维护性更高。而可维护性即代码的可读性,因为我们写的代码就是公司的财产,当需要其他人维护的时候,可读性更高的代码会让维护你代码的人更快上手。本文说的computed计算属性就是为了这一目的来的,计算属性可以让我们的代码看起来不臃肿,可读性和可维护性更高,所以在介绍使用Compition Api生成计算属性之前,我们需要先介绍下啥是计算属性。
1. 计算属性
1.1 计算属性的介绍和使用
Vue的表达式很强大也很方便,但是写简单的操作还行,复杂的操作虽然也没啥大问题,但是会让代码变得很臃肿,导致可读性变得很差,难以维护。引用官网的例子来了解计算属性。
.........省略开头代码.......
data() {
return {
author: {
name: 'John Doe',
books: [
'Vue 2 - Advanced Guide',
'Vue 3 - Basic Guide',
'Vue 4 - The Mystery'
]
}
}
}
.........
假设想根据 author 是否已有一些书籍来展示不同的信息,如果使用表达式的方式如下:
<p>是否有已经发布的书籍:</p>
<span>{{ author.books.length > 0 ? 'Yes' : 'No' }}</span>
上面的代码看起来已经显示得有点复杂了,万一我们需要在界面中的很多地方都这样写,就太臃肿了,同样的代码到处都在写。所以引入了计算属性来优化这个问题。也许很多小伙伴会说用方法抽取呀,后面会介绍为啥不用方法。
使用计算属性后上面的需求可以用如下的方式实现,我们可以使用Vue提供的computed关键字定义计算属性:
.............省略开头代码.....
data() {
return {
author: {
name: 'John Doe',
books: [
'Vue 2 - Advanced Guide',
'Vue 3 - Basic Guide',
'Vue 4 - The Mystery'
]
}
}
},
computed: {
// 一个计算属性的 getter
publishedBooksMessage() {
// `this` 指向当前组件实例
return this.author.books.length > 0 ? 'Yes' : 'No'
}
}
..........
在上面的代码中,我们在这里定义了一个计算属性 publishedBooksMessage。当我们更改此应用的 data 中 books 数组的值后,可以看到 publishedBooksMessage 也会随之改变。在模板中使用计算属性的方式和一般的属性并无二致。Vue 会检测到 this.publishedBooksMessage 依赖于 this.author.books,所以当 this.author.books 改变时,任何依赖于 this.publishedBooksMessage 的绑定都将同时更新。
(引用自Vue官网计算属性章节)
1.2 计算属性和方法的区别
现在我们来解释下为啥不用方法,Vue反而要提供一个计算属性呢?我们继续看例子来解释。还是用上面的例子,我们同样可以使用方法来完成需求
// 定义一个方法来判断是否有新发布的作品
methods: {
calculateBooksMessage() {
return this.author.books.length > 0 ? 'Yes' : 'No'
}
}
// 调用方法
<p>{{ calculateBooksMessage() }}</p>
如上面代码所示,当我们使用方法来实现上面的需求时,执行的结果确实是完全一致的,不同之处在于计算属性值会基于其响应式依赖被缓存。一个计算属性仅会在其响应式依赖更新时才重新计算。这意味着只要 author.books 不改变,无论多少次访问 ,publishedBooksMessage 都会立即返回先前的计算结果,而不用重复执行 getter 函数
也就是说,计算属性会做一个缓存,只要计算属性中参与计算的变量对应的依赖不更新,计算属性就会返回缓存的值,有更新才会重新计算。就比如本例中的books
,只要我们不往books中
添加新书,那么计算属性publishedBooksMessage
会一直返回之前计算的值,不会触发重新计算,而使用方法的话,每次都会去执行方法,无论是否加入新书,都会执行。这样就会浪费CPU资源,虽然不多,但是能省则省嘛。
使用计算属性的另一个好处就是快,试想下你有一个很大的list想要渲染出来,使用方法的话,无论你是否更新list都需要执行一遍遍历拿length的操作,但是使用计算属性,计算过一次后,只要后面没有更新,就可以使用缓存,这样就能提升页面的响应速度。
1.2 可写计算属性
计算属性默认是只读的。当你尝试修改一个计算属性时,你会收到一个运行时警告。因为计算属性主要是会缓存,如果随意的写会破坏之前缓存的值,导致下次取出缓存的值时导致值不是预期的。通常情况下我们只在某些特殊场景中才需要用到“可写”的属性,可写的计算属性可以通过同时提供 getter 和 setter 来创建,代码如下:
data() {
return {
firstName: 'John',
lastName: 'Doe'
}
},
computed: {
fullName: {
// getter
get() {
return this.firstName + ' ' + this.lastName
},
// setter
set(newValue) {
// 注意:我们这里使用的是解构赋值语法
[this.firstName, this.lastName] = newValue.split(' ')
}
}
}
在上面的代码中当调用this.fullName = ‘John Doe’ 时,setter 会被调用而 this.firstName 和 this.lastName 会随之更新,get()方法是在每次取值时都会调用,而set方法是每次赋值时都会调用。
使用Compition API 生成计算属性
在Compition API 中生成计算属性其实就是把传统Vue中使用的计算属性写到setup函数中,代码如下:
<!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>computed的使用</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="root"></div>
</body>
<script>
const app = Vue.createApp({
setup(){
const{ref, computed} = Vue;
const count = ref(0);
const handleClick = ()=>{
count.value += 1;
}
// 操作基本类型的值
// const countAddFive = computed(()=>{
// return count.value + 5;
// });
let countAddFive = computed({
get:() =>{
return count.value + 5;
},
set:(param)=>{
count.value = param - 5;
}
})
setTimeout(()=>{
countAddFive.value = 100;
},3000)
return {count,handleClick,countAddFive}
},
template:
`
<div>
<span @click="handleClick">{{count}}--------{{countAddFive}}</span>
</div>
`
});
const vm = app.mount('#root');
</script>
上面的代码中,我们在setup中使用计算属性时需要事先引入 const{ref, computed} = Vue;
然后就是在setup()中使用,用法很简单,在代码中已经 很清晰了。代码demo的意思也很简单,就是展示两个值count,和countAddFive,点击时
点击时,count的值加一,countAddFive加5,然后过了3秒后, 将countAddFive的值改成100,然后count的值会变成95,因为
set:(param)=>{
count.value = param - 5;
}
设置conutAddFive的值时会将count的值减5。
总结
本文主要介绍了计算属性和在Compition API 中使用计算属性,学完本文,我们需要了解到在什么情况下需要使用计算属性,计算属性和方法的区别。以及了解可写的计算属性如何使用。计算属性的使用可以极大的加快我们的界面响应速度,建议读者好好掌握计算属性的使用,然后在项目中根据场景将计算属性应用到对应的地方。