Vue3.x 官网
注:新版vue3的setup语法糖更为简洁
,详见 Vue3 script setup 语法糖,超爽体验
一、Composition API 简介
Vue2 时的方式在代码很少的时候,逻辑结构还是蛮清晰的,但是随着组件功能越来越多,代码量越来越大,整体内容全部放在其中肯定会显得臃肿。因为每个功能模块的代码会散落分布在各个位置,让整个项目的内容难以阅读和维护。如下图:
而到了 Vue3,它会根据逻辑功能来进行组织,把同一个功能的不同代码都放在一起,或者把它们单独拿出来放在一个函数中,所以 Composition API
又被称为基于函数组合的API:
1. setup 函数
setup 函数是 Vue3 中新增的函数,它是我们在编写组件时,使用 Composition API
的入口。
同时它也是 Vue3 中新增的一个生命周期函数,会在 beforeCreate
之前调用。因为此时组件的 data
和 methods
还没有初始化,因此在 setup 中是不能使用 this
的。所以 Vue 为了避免我们错误的使用,它直接将 setup 函数中的 this
修改成了undefined
。并且,我们只能同步使用setup函数,不能用async将其设为异步。
setup 函数接收两个参数 props
和 context
, 语法为:setup(props,context){}
props
props
里面包含父组件传递给子组件的所有数据。在子组件中使用 props
进行接收。
props
是响应式的, 当传入新的 props
时,会及时被更新。
由于是响应式的, 所以不可以使用 ES6 解构,解构会消除它的响应式。
父组件:
子组件(Sub.vue):
{{name}}{{age}}
context
context
里面包含 attrs
, slots
, emit
等数据方法:
attrs
:获取组件上的属性slots
:获取 slot 插槽的节点emit
:emit 方法(子组件向父组件传递数据)
父组件:
parent
子组件(Sub.vue):
Child
2. 生命周期
setup 函数是 Vue3 中新增的一个生命周期函数
- setup 函数会在
beforeCreate
之前调用,因为此时组件的data
和methods
还没有初始化,因此在 setup 中是不能使用this
的。 - 所以 Vue 为了避免我们错误的使用,它直接将 setup 函数中的
this
修改成了undefined
。 - setup函数,只能是同步的不能是异步的
Vue2.x (Option API) | Vue3.x (Composition API) |
---|---|
beforeCreate | setup |
created | setup |
beforeMount | onBeforeMount |
mounted | onMounted |
beforeUpdate | onBeforeUpdate |
updated | onUpdated |
beforeDestroy | onBeforeUnmount |
destroyed | onUnmounted |
activated | onActivated |
deactivated | onDeactivated |
errorCaptured | onErrorCaptured |
- - | onRenderTracked |
- - | onRenderTriggered |
初始化加载顺序:
setup
=> beforeCreate
=> created
=> onBeforeMount
=> onMounted
3. 返回值
setup
函数中返回一个对象,可以在模板中直接访问该对象中的属性和方法。
{{name1}} - {{name2}}
4. ref 与 reactive
创建一个响应式数据
- ref:任意类型(建议基本类型)数据的响应式引用(设置、获取值时需要加
.value
)。
ref 的本质是拷贝,修改数据是不会影响到原始数据。 - reactive:只能是复杂类型数据的响应式引用
- ref 基本类型:{{name1}}
- ref 复杂类型:{{name2.name}}
- reactive 复杂类型:{{name3.name}}
5. toRef 与 toRefs
也可以创建一个响应式数据
- toRef:用来给抽离响应式对象中的某一个属性,并把该属性包裹成 ref 对象,使其和原对象产生链接。
toRef 的本质是引用,修改响应式数据会影响原始数据。 - toRefs:用来把响应式对象转换成普通对象,把对象中的每一个属性,包裹成 ref 对象。
toRefs 就是 toRef 的升级版,只是toRefs 是把响应式对象进行转换,其余的特性和 toRef 无二
- {{name1}}
- {{name2.name.value}}
- {{name}}
6. readonly 只读属性
表示响应式对象不可修改
- {{nameObj.name}}
7. method方法
8. computed 计算属性
{{addCount}}
9. watch 与 watchEffect 监听属性
watch
函数:
用来侦听特定的数据源,并在回调函数中执行副作用。
默认情况是惰性的,也就是说仅在侦听的源数据变更时才执行回调。watchEffect
函数:
1.立即执行、立即监听(immediate)
2.自动会感知代码依赖(自动收集依赖),不需要传递监听的内容(不需要像watch
一样手动传入依赖)
3.无法获得变化前的值(oldVal)
{{name}}
{{nameObj.name}}
二、获取DOM节点
三、provide 与 inject
父组件向子组件传递数据与方法
父组件:
子组件(Sub.vue):
{{name}}
四、Teleport 传送门
Teleport
翻译过来是传送的意思,就像是哆啦 A 梦中的 「任意门」 ,任意门的作用就是可以将人瞬间传送到另一个地方。
举例:
我们希望 Dialog
渲染的 dom 和顶层组件是兄弟节点关系, 在 App.vue
文件中定义一个供挂载的元素:
定义一个 Dialog 组件 Dialog.vue
, 留意 to
属性, 与上面的 id选择器
一致:
title
I'am a Dialog.
DOM 渲染效果如下:
我们使用 teleport 组件
,通过 to 属性
,指定该组件渲染的位置在 App.vue
中,但是 Dialog 又是完全由 Dialog.vue
组件控制。
五、Suspense
Suspense组件用于在等待某个异步组件解析时显示后备内容。
在 Vue2.x 中经常遇到这样的场景:
...
加载中...
在异步数据没加载前,一般我们都会提供一个加载中( loading )的动画,当数据返回时配合 v-if
来控制数据显示。
现在 Vue3.x 新出的内置组件 Suspense
, 它提供两个template slot
, 刚开始会渲染一个 fallback
状态下的内容, 直到到达某个条件后才会渲染 default
状态的正式内容, 通过使用 Suspense
组件进行展示异步渲染就更加的简单。
...
Loading...
Suspense
组件 只是一个带插槽的组件,只是它的插槽指定了 default
和 fallback
两种状态。
六、碎片化节点 Fragment
在 Vue2.x 中, template
中只允许有一个根节点:
但是在 Vue3.x 中,可以有多个根元素,也可以有把文本作为根元素
七、插槽与作用域插槽
1. 插槽
父组件:
父组件
子组件(Child.vue
):
子组件
2. 作用域插槽
父组件:
{{scoped.myName}}
子组件: