Vue3提供了多种 API 来定义和管理组件,包括:组合,生命周期钩子,异步组件等

总结

Vue 3 提供了多种 API 来定义和管理组件,包括:

  • 组件定义:使用 defineComponent,定义组件的 datapropsmethodsemits 等。
  • 组合 API:使用 setuprefreactivecomputedwatchwatchEffect
  • 生命周期钩子:如 onMountedonUpdated 等。
  • provideinject:在组件树中传递和接收数据。
  • 异步组件:使用 defineAsyncComponent 按需加载组件。
  • useSlotsuseAttrs:访问组件插槽和属性。

这些 API 使得 Vue 3 组件的定义和管理更加灵活和强大。

1. 组件定义

使用 defineComponent 基本用法

defineComponent 是 Vue 3 中用于定义组件的一个 API,特别是在使用 TypeScript 时,它提供了类型安全和代码提示。

<template>
 <div>
    <p>Count: {{ count }}</p>
    <button @click="increment">Increment</button>
 </div>
</template>

import { defineComponent, ref } from 'vue';

export default defineComponent({
  name: 'MyComponent',
  setup() {
    const count = ref(0);
    const increment = () => {
      count.value++;
    };
    return { count, increment };
  },
});

组件选项

定义 data:是定义组件的响应式数据。虽然在 Vue 3 的组合 API 中,使用 setuprefreactive 是更推荐的方式,但你仍然可以使用 data 选项来定义状态。
export default defineComponent({
  data() {
    return {
      count: 0,
      message: 'Hello Vue 3'
    };
  }
});
定义 props :用于定义组件可以接收的属性。在 defineComponent 中,你可以使用对象语法来定义属性的类型、默认值和其他选项。
export default defineComponent({
  props: {
    title: {
      type: String, // 属性类型
      required: true, // 是否是必需的
    },
    count: {
      type: Number,
      default: 0 // 默认值
    }
  }
});
定义 emits:用于定义组件发射的事件。你可以指定一个事件的列表,也可以定义事件验证函数来确保事件名称和参数正确。
import { defineComponent } from 'vue';

export default defineComponent({
  emits: ['update'],
  methods: {
    update() {
      this.$emit('update');
    }
  }
});
定义 methods:用于定义组件的方法,这些方法可以在模板中调用。
export default defineComponent({
  methods: {
    greet() {
      console.log('Hello!');
    }
  }
});

2.组合 API 

 setup函数

Vue 3 组合 API 的核心。你可以在 setup 中定义响应式数据、计算属性、方法、生命周期钩子等。

import { defineComponent, ref } from 'vue';

export default defineComponent({
  setup(props, { emit }) {
    const count = ref(0);
    
    const increment = () => {
      count.value++;
      emit('update', count.value); // 使用 emit 发射事件
    };

    return { count, increment };
  }
});
定义计算属性 (computed)
import { defineComponent, computed, ref } from 'vue';

export default defineComponent({
  setup() {
    const firstName = ref('John');
    const lastName = ref('Doe');
    
    const fullName = computed(() => `${firstName.value} ${lastName.value}`);

    return { firstName, lastName, fullName };
  }
});

3.使用生命周期钩子

Vue 3 提供了组合 API 风格的生命周期钩子,类似于 Vue 2 中的生命周期选项,但在 setup 中使用。

import { defineComponent, onMounted, onUnmounted } from 'vue';

export default defineComponent({
  setup() {
    onMounted(() => {
      console.log('Component has been mounted');
    });

    onUnmounted(() => {
      console.log('Component has been unmounted');
    });
  }
});

4.使用 provideinject:

用于在组件树中提供和注入依赖数据。

在父组件中 provide 数据:

import { defineComponent, provide, ref } from 'vue';

export default defineComponent({
  setup() {
    const theme = ref('dark');
    provide('theme', theme);
  }
});

在子组件中 inject 数据:

import { defineComponent, inject } from 'vue';

export default defineComponent({
  setup() {
    const theme = inject('theme', 'light'); // 第二个参数是默认值
    return { theme };
  }
});

5. 异步组件:defineAsyncComponent

defineAsyncComponent 用于定义按需加载的异步组件。异步组件允许你在需要的时候动态加载组件,从而减少初始加载时间,提高应用性能。你可以通过一个工厂函数来定义一个异步组件,该函数返回一个 Promise,该 Promise 解析后会返回实际的组件。

基本用法

使用 defineAsyncComponent 按需加载一个组件:

import { defineAsyncComponent } from 'vue';

const AsyncComponent = defineAsyncComponent(() =>
  import('./MyAsyncComponent.vue') // 动态导入组件
);
使用异步组件

在父组件中,你可以像使用常规组件一样使用异步组件:

<template>
  <div>
    <!-- 使用异步组件 -->
    <AsyncComponent />
  </div>
</template>

<script>
import { defineComponent } from 'vue';
import AsyncComponent from './AsyncComponent'; // 导入异步组件

export default defineComponent({
  components: {
    AsyncComponent
  }
});
</script>
配置选项

defineAsyncComponent 还支持一些额外的配置选项,例如用于设置加载组件、错误组件和超时时间等:

import { defineAsyncComponent } from 'vue';

const AsyncComponent = defineAsyncComponent({
  loader: () => import('./MyAsyncComponent.vue'), // 必须:动态导入组件
  loadingComponent: LoadingComponent, // 可选:加载状态组件
  errorComponent: ErrorComponent, // 可选:错误状态组件
  delay: 200, // 可选:在显示加载组件之前的延迟时间(毫秒)
  timeout: 3000, // 可选:超时之后显示错误组件的时间(毫秒)
  onError(error, retry, fail, attempts) {
    if (attempts <= 3) { // 最大重试次数
      retry(); // 重试加载
    } else {
      fail(); // 失败处理
    }
  }
});

6. useSlotsuseAttrs

useSlotsuseAttrs 是 Vue 3 中提供的组合 API,用于访问组件的插槽 (slots) 和属性 (attrs)。这些 API 可以让你在 setup 函数中更直接地访问组件的插槽内容和非 props 的属性。

useSlots

useSlots 函数用于在组合 API 中访问当前组件的插槽内容。它返回一个对象,该对象包含所有命名插槽的函数,函数返回插槽内容的 VNode 数组。

使用示例:

<template>
  <div>
    <!-- 使用具名插槽 -->
    <slot name="header">Default Header</slot>
    <slot>Default Content</slot>
    <slot name="footer">Default Footer</slot>
  </div>
</template>

<script>
import { defineComponent, useSlots } from 'vue';

export default defineComponent({
  setup() {
    const slots = useSlots();

    // 使用插槽
    if (slots.header) {
      console.log('Header slot is provided');
    }

    return {};
  }
});
</script>
useAttrs

useAttrs 函数用于在组合 API 中访问传递给当前组件的非 props 的特性(例如自定义 HTML 属性)。useAttrs 返回一个响应式对象,该对象包含所有这些特性。

使用示例:

<template>
  <div v-bind="attrs">
    <!-- 使用组件传入的属性 -->
    <p>{{ attrs.someAttr }}</p>
  </div>
</template>

<script>
import { defineComponent, useAttrs } from 'vue';

export default defineComponent({
  setup() {
    const attrs = useAttrs(); // 获取非 props 属性
    return { attrs };
  }
});
</script>

组合使用示例

你可以同时使用 useSlotsuseAttrs 来处理插槽和非 props 的属性:

<template>
  <div v-bind="attrs">
    <header>
      <slot name="header">Default Header</slot>
    </header>
    <main>
      <slot>Default Content</slot>
    </main>
    <footer>
      <slot name="footer">Default Footer</slot>
    </footer>
  </div>
</template>

<script>
import { defineComponent, useSlots, useAttrs } from 'vue';

export default defineComponent({
  setup() {
    const slots = useSlots(); // 获取插槽
    const attrs = useAttrs(); // 获取非 props 的属性

    return { slots, attrs };
  }
});
</script>

总结

  • defineAsyncComponent 用于按需加载组件,可以提高性能。
  • useSlots 提供访问插槽内容的功能,适用于组合 API。
  • useAttrs 提供访问非 props 属性的功能,使得组件更加灵活。

这些 API 都使得 Vue 3 在处理组件逻辑、动态加载和插槽方面更加灵活和高效。

  • 21
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值