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})

  1. props: 和 vue2 中的 props 作用一样;

  2. attrs: 包含没有在 props 配置中声明的属性的对象, 相当于 this.$attrs;

  3. slots: 包含所有传入的插槽内容的对象, 相当于 this.$slots;

  4. emit: 用来分发自定义事件的函数, 相当于 this.$emit;

setup 执行的时机

  1. 在解析完 props、beforeCreate 之前执行(一次), 此时组件对象还没有创建(此时没有this);

  2. this 是 undefined, 不能通过 this 来访问 data/computed/methods/props,其实所有的 composition API 相关回调函数中也都不可以;

setup 的返回值

  1. 一般都返回一个对象: 为模板提供数据, 也就是模板中可以直接使用此对象中的所有属性/方法;

    • 返回对象中的属性会与 data 函数返回对象的属性合并成为组件对象的属性;
    • 返回对象中的方法会与 methods 中的方法合并成功组件对象的方法;
    • 如果有重名, setup 优先;
  2. 注意:

    • 一般不要混合使用: 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 某个依赖变化导致组件重新渲染时

父子组件声明周期顺序

示例代码

  1. 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>
    
  2. 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>
    

效果展示

  1. 初始化

  2. 更新

  3. 销毁

面试题

composition api相比于option api有哪些优势?

  1. Vue Composition APIVue 3 中引入的新特性,旨在解决 Vue 2 中使用 Options API 时的一些局限性;Composition API 提供了一种更灵活、更可组合的方式来组织组件逻辑,使代码更易于维护和重用;

  2. 主要特性和理解:

    1. 可组合性:通过组合函数 (composable functions),可以将组件逻辑抽离成独立的函数;这些函数可以在多个组件中复用,提升了代码的可维护性;
    2. 更好的逻辑组织:在 Options API 中,组件逻辑通常被分散在多个选项中 (如 data、methods、computed 等),而 Composition API 允许将相关逻辑集中在一起,使代码更清晰;
    3. 减少命名冲突:通过使用组合函数,每个组合函数都有自己独立的作用域,避免了全局命名空间的污染和命名冲突;
    4. TypeScript 支持Composition API 天然支持 TypeScript,提供了更好的类型推断和类型检查,提升了开发体验;
    5. API
      • setup:这是 Composition API 的核心函数,用于定义组件的初始化逻辑;在 setup 中可以使用 Vue 提供的 reactive、ref、computedAPI 来处理响应式状态;
      • reactive 和 ref:用于创建响应式状态,reactive 用于创建一个深度响应的对象,而 ref 创建一个单一响应的值;
      • computed:用于定义计算属性,与 Options API 中的 computed 类似;
      • watch 和 watchEffect:用于监听和响应数据变化;
打赏作者
您的打赏是我前进的动力
微信
支付宝
评论

你好👏🏻,我是 ✍🏻   疯狂 codding 中...

粽子

这有关于前端开发的技术文档和你分享。

相信你可以在这里找到对你有用的知识和教程。

了解更多

目录

  1. 1. setup
    1. 1.1. setup 的参数
    2. 1.2. setup 执行的时机
    3. 1.3. setup 的返回值
  2. 2. 生命周期
    1. 2.1. 生命周期图解
    2. 2.2. 生命周期函数
    3. 2.3. 新增钩子函数说明
    4. 2.4. 父子组件声明周期顺序
      1. 2.4.1. 示例代码
      2. 2.4.2. 效果展示
  3. 3. 面试题
    1. 3.1. composition api相比于option api有哪些优势?