您现在的位置是:首页 >技术杂谈 >Vue之使用Compition API生成计算属性computed网站首页技术杂谈

Vue之使用Compition API生成计算属性computed

海塔灯 2024-06-21 00:01:02
简介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 中使用计算属性,学完本文,我们需要了解到在什么情况下需要使用计算属性,计算属性和方法的区别。以及了解可写的计算属性如何使用。计算属性的使用可以极大的加快我们的界面响应速度,建议读者好好掌握计算属性的使用,然后在项目中根据场景将计算属性应用到对应的地方。

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。