Vue3 – Composition Api

本文介绍了Vue3中的CompositionApi,一种新的组件编程模式,通过setup函数整合组件选项,实现响应式编程。重点讲解了reactive、ref、readonly等API的使用和原理,以及如何在setup中正确使用这些工具以提高代码清晰度和可维护性。
摘要由CSDN通过智能技术生成

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

一、Composition Api是什么?

  • 🍕🍕🍕 在vue2中,编写组件的方式都是一个一个固定的选项(options),例如,data定义数据methods中定义方法computed中定义计算属性watch中监听属性改变(也包括生命周期钩子)
  • 随着项目的不断迭代,也就意味着功能越来越多,当组件变得更大更复杂时、逻辑关注点的列表就会增长、同一个功能的逻辑就会被拆分的很分散; 后期迭代开发会更挠头😒😒😒
  • 如果能将同一个逻辑关注点相关的代码 放在一起 那么开发不就更清晰了吗
    🍔🍔🍔 vue3新提出的概念,Composition Api 就是为了解决这个问题

二、使用步骤

1.写在哪

  • 我们需要一个可以实际使用它的地方
  • 在Vue组件中,setup函数

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

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

2.函数的使用

  • 函数的参数
  • 函数的返回值(模板中可以使用)

既然是一个函数,那么可以有返回值,作用可以理解为替代data选项

注意:必须返回 模板中才能渲染

甚至是我们可以返回一个执行函数来代替在methods中定义的方法:

setup(){
	let message = "message";
	let counter = 100;
	const increment = ()=>{
		counter++;
	}
	const decrement = ()=>{
		counter--;	
	}
	return{message,counter,increment,decrement} ;
}

如果我们将 counter 在 increment 或者 decrement进行操作时,是否可以实现界面的响应式呢?

  • 不是响应式
  • 因为对于默认定义的变量,默认情况下,Vue并不会跟踪它 的变化,也不会引起界面的响应式变化。

reactive函数

  • vue提供了api,用来响应式定义复杂数据,
  • reactive({})
  • 注意:对传入的类型是有限制的,要求必须传入一个对象或者数组。

为什么它定义的数据就变成响应式的呢?

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

ref

  • vue提供用来定义响应式基本类型的api
  • 会返回一个可变的响应式对象,该对象作为一个响应式的引用 维护着它内部的值,这也是名称的由来。
  • 它内部的值是在ref的 value 属性中被维护的;
const message = ref("信息")
  • 注意:
  • 模板中引入ref的值时,Vue会自动帮助我们进行解包操作,所以我们并不需要在模板中通过 ref.value 的方式来使用;
  • 但是在 setup 函数内部,它依然是一个 ref引用, 所以对其进行操作时,我们依然需要使用 ref.value的方式;

ref自动解包

  • 模板中的解包是浅层的解包
  • 如果我们将ref放到一个reactive的属性当中,那么在模板中使用时,它会自动解包

readonly

  • 背景:reactive或者ref可以获取到一个响应式的对象,但是某些情况下,我们传入给其他地方(组件)的这个响应式对象希望在另外一个地方(组件)被使用,但是不能被修改,这个时候如何防止这种情况的出现
  • 提供了readonly的方法
  • readonly会返回原始对象的只读代理(也就是它依然是一个Proxy,这是一个proxy的set方法被劫持,并且不能对其进行修
    改)

在开发中常见的readonly方法会传入三个类型的参数

  • 类型一:普通对象
  • 类型二:reactive返回的对象
  • 类型三:ref的对象

readonly的使用

  • 在readonly的使用过程中,有如下规则
  • readonly返回的对象都是不允许修改
  • 但是经过readonly处理的原来的对象允许被修改的
  • 比如 const info = readonly(obj),info对象是不允许被修改的
  • 当obj被修改时,readonly返回的info对象也会被修改
  • 但是我们不能去修改readonly返回的对象info
  • 本质上就是readonly返回的对象的setter方法被劫持了

Reactive判断的API

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

toRefs

  • 如果我们使用ES6的解构语法,对reactive返回的对象进行解构获取值,那么之后无论是修改解构后的变量,还是修改reactive
    返回的state对象,数据都不再是响应式
const state = reactive({
	message:'信息',
	age:20
});
const { message,age } = state
  • 那么有没有办法让我们解构出来的属性是响应式的呢
  • 提供了一个toRefs的函数,可以将reactive返回的对象中的属性都转成ref
  • 那么我们再次进行结构出来的 message和 age 本身都是 ref的
const { message,age } = toRefs(state)
  • 相当于已经在state.name和ref.value之间建立了 链接,任何一个修改都会引起另外一个变化

toRef

  • 如果我们只希望转换一个reactive对象中的属性为ref, 那么可以使用toRef的方法
const name = toRef(state,'name');
const {age} = state;
const addName = ()=>{
	state.name = 'dfh'
}

ref其他的API

  • unref
  • 如果我们想要获取一个ref引用中的value,那么也可以通过unref方法
  • 如果参数是一个 ref,则返回内部值,否则返回参数本身
  • isRef
  • 判断值是否是一个ref对象
  • shallowRef
  • 创建一个浅层的ref对象
  • triggerRef
  • 手动触发和 shallowRef 相关联的副作用

setup不可以使用this

  • this并没有指向当前组件实例
  • 并且在setup被调用之前,data、computed、methods等都没有被解析
  • 所以无法在setup中获取this
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值