setup
- 不同于 ReactivityApi,CompositionApi 提供的函数很多是与组件深度绑定的,不能脱离组件而存在
- 新的 option, 所有的组合 API 函数都在此使用, 只在初始化时执行一次
- 函数如果返回对象, 对象中的属性或方法, 模板中可以直接使用;
<template>
<div>hello</div>
<h1>{{ number }}</h1>
</template>
<script lang="ts">
// defineComponent函数,目的是定义一个组件,内部可以传入一个配置对象
import { defineComponent } from "vue";
// defineComponent 最重要的是:在 TS 下,给予了组件正确的参数类型推断
export default defineComponent({
// 当前组件的名字是 App
name: "App",
// 测试代码 setup 是组合 API 中第一个要使用的函数
setup() {
const number = 10;
return {
number,
};
},
});
</script>
setup 的参数
setup(props, context) / setup(props, {attrs, slots, emit})
-
props: 和 vue2 中的 props 作用一样;
-
attrs: 包含没有在 props 配置中声明的属性的对象, 相当于 this.$attrs;
-
slots: 包含所有传入的插槽内容的对象, 相当于 this.$slots;
-
emit: 用来分发自定义事件的函数, 相当于 this.$emit;
setup 执行的时机
-
在解析完 props、beforeCreate 之前执行(一次), 此时组件对象还没有创建(此时没有this);
-
this 是 undefined, 不能通过 this 来访问 data/computed/methods/props,其实所有的 composition API 相关回调函数中也都不可以;
setup 的返回值
-
一般都返回一个对象: 为模板提供数据, 也就是模板中可以直接使用此对象中的所有属性/方法;
- 返回对象中的属性会与 data 函数返回对象的属性合并成为组件对象的属性;
- 返回对象中的方法会与 methods 中的方法合并成功组件对象的方法;
- 如果有重名, setup 优先;
-
注意:
- 一般不要混合使用: methods 中可以访问 setup 提供的属性和方法, 但在 setup 方法中不能访问 data 和 methods;
- setup 不能是一个 async 函数: 因为返回值不再是 return 的对象, 而是 promise, 模板获取不到 return 对象中的属性数据;
生命周期
生命周期图解
生命周期函数
vue2 option api | vue3 option api | vue 3 composition api |
---|---|---|
beforeCreate | beforeCreate | 不再需要,代码可直接置于 setup 中 |
created | created | 不再需要,代码可直接置于 setup 中 |
beforeMount | beforeMount | onBeforeMount |
mounted | mounted | onMounted |
beforeUpdate | beforeUpdate | onBeforeUpdate |
updated | updated | onUpdated |
beforeDestroy | 改 beforeUnmount | onBeforeUnmount |
destroyed | 改 unmounted | onUnmounted |
errorCaptured | errorCaptured | onErrorCaptured |
- | 新 renderTracked | onRenderTracked |
- | 新 renderTriggered | onRenderTriggered |
新增钩子函数说明
DebuggerEvent:
- target: 跟踪或触发渲染的对象
- key: 跟踪或触发渲染的属性
- type: 跟踪或触发渲染的方式
钩子函数 | 参数 | 执行时机 |
---|---|---|
renderTracked | DebuggerEvent | 渲染vdom收集到的每一次依赖时 |
renderTriggered | DebuggerEvent | 某个依赖变化导致组件重新渲染时 |
父子组件声明周期顺序
示例代码
-
app.vue
<template> <h2>App父级组件</h2> <button @click="isShow = !isShow">切换显示</button> <hr /> <!-- 子级组件 --> <Child v-if="isShow" /> </template> <script lang="ts"> // 引入子级组件Child import Child from './components/Child.vue'; import { defineComponent, ref } from 'vue'; export default defineComponent({ name: 'App', // 注册组件 components: { Child, }, setup() { const isShow = ref(true); return { isShow, }; }, }); </script>
-
child.vue
<template> <h2>Child子级组件</h2> <h4>msg:{{ msg }}</h4> <button @click="update">更新数据</button> </template> <script lang="ts"> import { defineComponent, ref, onBeforeMount, onMounted, onBeforeUpdate, onUpdated, onBeforeUnmount, onUnmounted } from 'vue'; export default defineComponent({ name: 'Child', // vue2.x 中的生命周期钩子 beforeCreate() { console.log('2.x中的beforeCreate...'); }, created() { console.log('2.x中的created...'); }, beforeMount() { console.log('2.x中的beforeMount...'); }, mounted() { console.log('2.x中的mounted...'); }, beforeUpdate() { console.log('2.x中的beforeUpdate...'); }, updated() { console.log('2.x中的updated...'); }, // vue2.x 中的 beforeDestroy 和 destroyed 这两个生命周期在 vue3 中改名了,所以,不能再使用了 beforeUnmount() { console.log('2.x中的beforeUnmount...'); }, unmounted() { console.log('2.x中的unmounted...'); }, setup() { console.log('3.0中的setup'); // 响应式的数据 const msg = ref('abc'); // 按钮点击事件的回调 const update = () => { msg.value += '==='; }; onBeforeMount(() => { console.log('3.0中的onBeforeMount'); }); onMounted(() => { console.log('3.0中的onMounted'); }); onBeforeUpdate(() => { console.log('3.0中的onBeforeUpdate'); }); onUpdated(() => { console.log('3.0中的onUpdated'); }); onBeforeUnmount(() => { console.log('3.0中的onBeforeUnmount'); }); onUnmounted(() => { console.log('3.0中的onUnmounted'); }); return { msg, update, }; }, }); </script>
效果展示
-
初始化
-
更新
-
销毁
面试题
composition api相比于option api有哪些优势?
从两个方面回答:
- 为了更好的逻辑复用和代码组织
- 更好的类型推导
-
有了 composition api 配合 reactivity api,可以在组件内部进行更加细粒度的控制,使得组件中不同的功能高度聚合,提升了代码的可维护性;对于不同组件的相同功能,也能够更好的复用;
-
相比于 option api ,composition api 中没有了指向奇怪的 this ,所有的 api 变得更加函数式,这有利于和类型推断系统比如 TS 深度配合;
css 工程化👉 PostCss
上一篇