写点什么

原来 Vue3 的 computed 属性还能这么用啊🔥

作者:渔戈
  • 2022-10-21
    广东
  • 本文字数:2913 字

    阅读完需:约 1 分钟

Hello,又见面了,我是渔戈!

我们之前已经跟 Vue3 来了一场美丽的邂逅了,也介绍了 Vue3 的一些基本指令,今天我们就来讲讲 Vue3 的 Options-API


相关文章:邂逅Vue3


Vue3的基本指令

1.复杂 data 的处理方式

我们知道,在模板中可以直接通过插值语法显示一些 data 中的数据。但是在某些情况,我们可能需要对数据进行一些转化后再显示,或者需要将多个数据结合起来进行显示.比如我们需要对多个 data 数据进行运算、三元运算符来决定结果、数据进行某种转化后显示.


在模板中使用表达式,可以非常方便的实现,但是设计它们的初衷是用于简单的运算,模板中放入太多的逻辑会让模板过重和难以维护,且如果多个地方都使用到,那么会有大量重复的代码.那么还有其他的解决方法吗?


那就是计算属性 computed

2.认识计算属性 computed

2.1 什么是计算属性呢?

  • 官方并没有给出直接的概念解释

  • 而是说:对于任何包含响应式数据的复杂逻辑,你都应该使用计算属性

  • 计算属性将被混入到组件实例中。所有 getter 和 setter 的 this 上下文自动地绑定为组件实例;

2.2 计算属性的用法:

  • 选项:computed

  • 类型:{ [key: string]: Function | { get: Function, set: Function } }

2.3 计算属性的基础示例

模板中的表达式虽然方便,但也只能用来做简单的操作。如果在模板中写太多逻辑,会让模板变得臃肿,难以维护。比如说,我们有这样一个包含嵌套数组的对象:


export default {  data() {    return {      author: {        name: 'John Doe',        books: [          'Vue 2 - Advanced Guide',          'Vue 3 - Basic Guide',          'Vue 4 - The Mystery'        ]      }    }  }}
复制代码


我们想根据 author 是否已有一些书籍来展示不同的信息:


<p>Has published books:</p><span>{{ author.books.length > 0 ? 'Yes' : 'No' }}</span>
复制代码


这里的模板看起来有些复杂。我们必须认真看好一会儿才能明白它的计算依赖于 author.books。更重要的是,如果在模板中需要不止一次这样的计算,我们可不想将这样的代码在模板里重复好多遍。


那有什么方法可以将逻辑抽离出去呢?


可以,其中一种方式就是将逻辑抽取到一个 method 中,放到 methods 的 options 中;


但是,这种做法有一个直观的弊端,就是所有的 data 使用过程都会变成了一个方法的调用(我们这里暂且不谈论这个方法)


另外一种方式就是使用计算属性 computed


因此我们推荐使用计算属性来描述依赖响应式状态的复杂逻辑。这是重构后的示例:


export default {  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'    }  }}
复制代码


<p>Has published books:</p><span>{{ publishedBooksMessage }}</span>
复制代码


我们在这里定义了一个计算属性 publishedBooksMessage


更改此应用的 data 中 books 数组的值后,可以看到 publishedBooksMessage 也会随之改变。


在模板中使用计算属性的方式和一般的属性并无二致。Vue 会检测到 this.publishedBooksMessage 依赖于 this.author.books,所以当 this.author.books 改变时,任何依赖于 this.publishedBooksMessage 的绑定都将同时更新。

2.4 案例讲解

案例一:我们有两个变量:firstName 和 lastName,希望它们拼接之后在界面上显示;


案例二:我们有一个分数:score


  • 当 score 大于 60 的时候,在界面上显示及格;

  • 当 score 小于 60 的时候,在界面上显示不及格;


案例三:我们有一个变量 message,记录一段文字:比如 Hello World


  • 某些情况下我们是直接显示这段文字;

  • 某些情况下我们需要对这段文字进行反转;

2.4.1 实现思路

  1. 思路一:在模板语法中直接使用表达式;

  2. 思路二:使用 method 对逻辑进行抽取;

  3. 思路三:使用计算属性 computed;

2.4.2 思路一:模板语法

  <div id="app"></div>  <template id="my-app">    <h2>{{firstName + " " + lastName}}</h2>    <h2>{{score >= 60 ? '及格': '不及格'}}</h2>    <h2>{{message.split(" ").reverse().join(" ")}}</h2>  </template>  <script src="../js/vue.js"></script>  <script>    const App = {      template: '#my-app',      data() {        return {          firstName: "Kobe",          lastName: "Bryant",          score: 80,          message: "Hello World"        }      }    }    Vue.createApp(App).mount('#app');  </script>
复制代码


  • 缺点一:模板中存在大量的复杂逻辑,不便于维护(模板中表达式的初衷是用于简单的计算);

  • 缺点二:当有多次一样的逻辑时,存在重复的代码;

  • 缺点三:多次使用的时候,很多运算也需要多次执行,没有缓存;

2.4.3 思路二:method 实现

div id="app"></div>
<template id="my-app"> <h2>{{getFullName()}}</h2> <h2>{{getResult()}}</h2> <h2>{{getReverseMessage()}}</h2> </template>
<script src="../js/vue.js"></script> <script> const App = { template: '#my-app', data() { return { firstName: "Kobe", lastName: "Bryant", score: 80, message: "Hello World" } }, methods: { getFullName() { return this.firstName + " " + this.lastName; }, getResult() { return this.score >= 60 ? "及格": "不及格"; }, getReverseMessage() { return this.message.split(" ").reverse().join(" "); } } }
Vue.createApp(App).mount('#app'); </script>
复制代码


  • 缺点一:我们事实上先显示的是一个结果,但是都变成了一种方法的调用;

  • 缺点二:多次使用方法的时候,没有缓存,也需要多次计算

2.4.3 思路三:computed 实现

<div id="app"></div>  <template id="my-app">    <h2>{{fullName}}</h2>    <h2>{{result}}</h2>    <h2>{{reverseMessage}}</h2>  </template>  <script src="../js/vue.js"></script>  <script>    const App = {      template: '#my-app',      data() {        return {          firstName: "Kobe",          lastName: "Bryant",          score: 80,          message: "Hello World"        }      },      computed: {        // 定义了一个计算属性叫fullname        fullName() {          return this.firstName + " " + this.lastName;        },        result() {          return this.score >= 60 ? "及格" : "不及格";        },        reverseMessage() {          return this.message.split(" ").reverse().join(" ");        }      }    }    Vue.createApp(App).mount('#app');  </script>
复制代码


好了,关于计算属性 computed 的讲解就到这里了,有什么问题的同学,可以在评论区进行讨论,创作不易,请留下你到达的痕迹!

发布于: 刚刚阅读数: 4
用户头像

渔戈

关注

还未添加个人签名 2022-10-14 加入

还未添加个人简介

评论

发布
暂无评论
原来Vue3的computed属性还能这么用啊🔥_Vue_渔戈_InfoQ写作社区