持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第28天,点击查看活动详情juejin.cn/post/714765…
今天学习了很多关于vue3组合式api的知识,分享给大家。
组合式API
里面都是函数。在这里创建一个数据,是通过方法创建出来一堆数据
- 响应式API:
- 生命周期钩子:
- 依赖注入:
Vue3的组合式API优点
(1)有更高效的灵活性
处理相同逻辑关注点的代码被强制拆分在了不同的选项中,位于文件的不同部分。而组合式api里可以把功能相联系的代码放在一部分,维护起来也比较方便。
(2)更好的类型推导
TS就是里面接了强制类型系统。其他的和原来一模一样。如果没有声明类型,打包会报错。而vue里内置了这个类型推导(指的就是vue会自动帮我们加类型声明,而且基本不会错。)。所以它俩经常结合一起使用,vue从而对TS的支持更好。
(3)更小的生产包体积
选项式API是生成了一个对象。使用这里的方法和属性都需要通过this访问,对象(即this)里面的代码不好压缩。而组合式API里面可以直接使用,不需要使用this,所以压缩式会更好。
(4)更好的复用逻辑
Vue2中对逻辑复用都是放在mxins里,而组合式API解决了mixins的所有缺陷。 mixins的缺陷:
- 不清晰的数据来源:如果一个组件里使用多个mixins,多了就不知道具体来源于哪个mixins了。
- 命名冲突:组合式API里可以把引进来的进行重命名
as - 隐式的跨mixins交流。如果组件里使用了Amixins里的数据,而Amixins里的数据可能用到了Bmixins,这样的话就需要把Amixins和Bmixins都引入,比较麻烦。而Vue3中就是普通的函数传参。 取舍: 舍弃了选项式中手把手教我们该把代码放在哪里。例如Vue2中不用思考就知道事件函数就是放在methods里,组件就放在components里。
组合式API里的模板和选项式里的没有任何变化。
setup
声明响应式状态
通过reactive方法创建一个响应式的对象或数组。注意:reactive()只能创建对象和数组
import {reactive} from "vue";
//可以写多个reactive
const state = reactive({count:'0'});
//这样创建完以后count就是响应式的了。
//count改变视图就会更新
- 组合式API里没有methods了,有watch和computed。直接把事件函数写在
<script>标签内,也不需要在通过this访问。 - DOM更新时机(和选项式API里是一样的,都是异步更新,可使用
nextTick(()=> {})方法可立刻访问到最新的DOM)
深层响应性
在 Vue 中,状态都是默认深层响应式的。这意味着即使在更改深层次的对象或数组,你的改动也能被检测到。
- 如果状态的值又是一个对象,深层对象改变也会更新view。
- 可通过
shallowReactive()方法创建浅层响应式 - 如果一个对象经过proxy处理了,再把它经过proxy进行代理,得到的还是它本身。
reactive()的局限性
- 如果把state里的数据赋值给一个变量,改变这个变量,对state里的键值没影响。解构出来的也没影响
- 仅对对象类型有效(对象、数组和
Map、Set这样的集合类型),而对string、number和boolean这样的 原始类型 无效。
reactive()创建的响应式数据什么时候会丢失响应式?
解答:当我们将响应式对象的属性赋值或解构至本地变量时,或是将该属性传入一个函数时,我们会失去响应性
- 可以用ref()方法定义响应式变量
- 作用:该方法允许我们定义一个任何类型的值,并具有响应式。
//通过ref创建响应式数据:
import { ref } from 'vue'
count obj = ref( {num:0} )
//读取:obj.value.num
const count = ref(0);//0就是基础的number类型,是响应式的
读取:通过这种方式创建出来的count是个对象,所以读取时通过`count.value`读取.
但注意:在模板里不需要.value直接写<div>{{count}}</div>
- 这种方式创建内部也是调用了
reactive方法。 - ref在一般对象上时解构响应式不会丢失,也就是一个对象通过自面量式创建,键名自定义,键值是ref()方法返回的对象,进行解构时,不丢失响应式。
const object = { foo: ref(1) }- 不是顶层的ref()在模板中也会自动解包,相当于省略.value,但是如果想在模板中进行计算,必须加上
.value,要不然的话时object.foo+1,object.foo是个对象,模板输出直接输出对象,但是得到的是1这个值。所以不能直接做运算,想进行计算,需要通过obj.value.foo+1
ref 在响应式对象中的解包
const count = ref(0) ;
const state = reactive({ count });//这时候不需要写.value,会自动解包
- 只有当嵌套在一个深层响应式对象内时,才会发生 ref 解包。当其作为浅层响应式对象的属性被访问时不会解包。
- 跟响应式对象不同,当 ref 作为响应式数组或像
Map这种原生集合类型的元素被访问时,不会进行解包。
ref响应性语法糖
注意:该方法在实验阶段。
<script setup>
let count = $ref(0)
function increment() { // 无需 .value ,就可以读取count的值
count++
}
</script>
<template>
<button @click="increment">{{ count }}</button>
</template>
readonly()
接受一个对象 (不论是响应式还是普通的) 或是一个 ref,返回一个原值的只读代理。 通俗的讲就是被readonly()方法包裹的数据是只读的,不能进行修改。