当前位置:   article > 正文

vue3的Composition API详解,包含hook的思想_vue3 composition

vue3 composition

一、Options API的弊端

Vue2中,我们编写组件的方式是Options API

  • Options API的一大特点就是在对应的属性中编写对应的功能模块
  • 比如data定义数据、methods中定义方法、computed中定义计算属性、watch中监听属性改变,也包括生命周期钩子

但是这种代码有一个很大的弊端

  • 当我们实现某一个功能时,这个功能对应的代码逻辑被拆分到各个属性中
  • 当我们组件变得更大、更复杂时,逻辑关注点的列表就会增长,那么同一个功能的逻辑就会被拆分的很分散
  • 尤其对于那些一开始没有编写这些组件的人来说,这个组件的代码是难以阅读和理解

如果我们能将同一个逻辑关注点相关的代码收集在一起会更好

  • 这就是Composition API想要做的事情,以及可以帮助我们完成的事情
  • 也有人把Vue CompositionAPI简称为VCA

二、认识Composition API

那么既然知道Composition API想要帮助我们做什么事情,接下来看一下到底是怎么做呢?

  • 为了开始使用Composition API,我们需要有一个可以实际使用它(编写代码)的地方
  • 在Vue组件中,这个位置就是 setup 函数

setup其实就是组件的另外一个选项

  • 只不过这个选项强大到我们可以用它来替代之前所编写的大部分其他选项
  • 比如methods、computed、watch、data、生命周期等等

三、setup

1、setup函数的参数

我们先来研究一个setup函数的参数,它主要有两个参数

  • 第一个参数:props
  • 第二个参数:context

props非常好理解,它其实就是父组件传递过来的属性会被放到props对象中,我们在setup中如果需要使用,那么就可以直接通过props参数获取

  • 对于定义props的类型,我们还是和之前的规则是一样的,在props选项中定义
  • 并且在template中依然是可以正常去使用props中的属性,比如message
  • 如果我们在setup函数中想要使用props,那么不可以通过 this 去获取(后面我会讲到为什么)
  • 因为props有直接作为参数传递到setup函数中,所以我们可以直接通过参数来使用即可

另外一个参数是context,我们也称之为是一个SetupContext,它里面包含三个属性

  • attrs:所有的非prop的attribute
  • slots:父组件传递过来的插槽(这个在以渲染函数返回时会有作用,后面会讲到)
  • emit:当我们组件内部需要发出事件时会用到emit(因为我们不能访问this,所以不可以通过 this.$emit发出事件)

下面通过一个例子来说明怎样使用这两个参数
假设我们现在有一个home组件,里面接收一个props
在这里插入图片描述
假设app.vue为父组件,传一个message的prop属性,和id、class两个非prop属性
在这里插入图片描述
在这里插入图片描述

2、setup函数的返回值

setup既然是一个函数,那么它也可以有返回值,它的返回值用来做什么呢?

  • setup的返回值可以在模板template中被使用
  • 也就是说我们可以通过setup的返回值来替代data选项

还是上面的那个例子
在这里插入图片描述
甚至是我们可以返回一个执行函数代替在methods中定义的方法
在这里插入图片描述
但是,如果我们将 counter 在 increment 或者 decrement进行操作时,是否可以实现界面的响应式呢?

  • 答案是不可以
  • 这是因为对于一个定义的变量来说,默认情况下,Vue并不会跟踪它的变化,来引起界面的响应式操作

上面的示例,通过控制台可以发现,counter的值确实发生了改变,但在页面上并不会看到跟着一起改变

3、setup不可以使用this

在这里插入图片描述

4、Reactive API

如果想为在setup中定义的数据提供响应式的特性,那么我们可以使用reactive的函数

还是上面的例子,按照下面这样写就可以响应式了,counter会在页面随着点击发生改变
在这里插入图片描述
那么这是什么原因呢?为什么就可以变成响应式的呢?

  • 这是因为当我们使用reactive函数处理我们的数据之后数据再次被使用时就会进行依赖收集
  • 数据发生改变时,所有收集到的依赖都是进行对应的响应式操作(比如更新界面)
  • 事实上,我们编写的data选项,也是在内部交给了reactive函数将其编程响应式对象的

Reactive判断的API

  • isProxy
    检查对象是否是由 reactive 或 readonly创建的 proxy
  • isReactive
    检查对象是否是由 reactive创建的响应式代理
    如果该代理是 readonly 建的,但包裹了由 reactive 创建的另一个代理,它也会返回 true;
  • isReadonly
    检查对象是否是由 readonly 创建的只读代理
  • toRaw
    返回 reactive 或 readonly 代理的原始对象(不建议保留对原始对象的持久引用。请谨慎使用)。
  • shallowReactive
    创建一个响应式代理,它跟踪其自身 property 的响应性,但不执行嵌套对象的深层响应式转换 (深层还是原生对象)。
  • shallowReadonly
    创建一个 proxy,使其自身的 property 为只读,但不执行嵌套对象的深层只读转换(深层还是可读、可写的)。

5、Ref API

1、基本使用

reactive API对传入的类型有限制的,它要求我们必须传入的是一个对象或者数组类型

  • 如果我们传入一个基本数据类型(String、Number、Boolean)会报一个警告
    在这里插入图片描述
    这个时候Vue3给我们提供了另外一个API:ref API
  • ref 会返回一个可变的响应式对象,该对象作为一个 响应式的引用 维护着它内部的值,这就是ref名称的来源
  • 它内部的值是在ref的 value 属性中被维护
    在这里插入图片描述
    这里有两个注意事项:
  • 模板中引入ref的值时,Vue会自动帮助我们进行解包操作,所以我们并不需要在模板中通过 ref.value 的方式来使用
  • 但是在 setup 函数内部,它依然是一个 ref引用, 所以对其进行操作时,我们依然需要使用 ref.value的方式

2、Ref自动解包

模板中的解包是浅层的解包
在这里插入图片描述

3、ref其他的API

  • unref
  • 如果我们想要获取一个ref引用中的value,那么也可以通过unref方法
  • 如果参数是一个 ref,则返回内部值,否则返回参数本身
  • 这是val = isRef(val) ? val.value : val的语法糖函数
  • isRef
  • 判断值是否是一个ref对象
  • shallowRef
  • 创建一个浅层的ref对象
  • triggerRef
  • 手动触发和 shallowRef 相关联的副作用
    在这里插入图片描述

6、readonly

1、认识readonly

我们通过reactive或者ref可以获取到一个响应式的对象,但是某些情况下,我们传入给其他地方(组件)的这个响应式对象希望在另外一个地方(组件)被使用但是不能被修改

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号