Skip to content
📈0️⃣

异步组件

异步组件

在 Vue 3 中,异步组件的使用方式与 Vue 2 相比发生了一些变化。在 Vue 3 中,我们可以使用defineAsyncComponent函数来定义和使用异步组件。下面是一个详细的代码示例:

defineAsyncComponent

示例:

vue
<template>
  <div>
    <button @click="loadComponent">加载异步组件</button>
    <component :is="dynamicComponent" v-if="dynamicComponent" />
    <p v-else>点击按钮加载组件</p>
  </div>
</template>

<script setup>
import { ref, defineAsyncComponent } from "vue";

const dynamicComponent = ref(null);

const loadComponent = async () => {
  const { default: DynamicComponent } = await import("./DynamicComponent.vue");
  dynamicComponent.value = defineAsyncComponent(() => DynamicComponent);
};
</script>

在上述代码中,我们首先引入异步组件。如果动态组件存在,则渲染组件;否则,显示提示信息。

需要注意的是,在 Vue 3 中,异步组件返回的是一个函数。因此,在使用动态组件时,我们需要将其传递给is属性。

另外,如果你希望添加异步组件的加载状态,你可以在加载组件过程中设置一个加载状态变量,并根据该变量来显示加载状态信息。

vue
<template>
  <div>
    <button @click="loadComponent" :disabled="isLoading">加载异步组件</button>
    <div v-if="isLoading">加载中...</div>
    <component :is="dynamicComponent" v-else-if="dynamicComponent" />
    <p v-else>点击按钮加载组件</p>
  </div>
</template>

<script setup>
import { ref, defineAsyncComponent } from "vue";

const dynamicComponent = ref(null);
const isLoading = ref(false);

const loadComponent = async () => {
  isLoading.value = true;

  const { default: DynamicComponent } = await import("./DynamicComponent.vue");
  dynamicComponent.value = defineAsyncComponent(() => DynamicComponent);

  isLoading.value = false;
};
</script>

在上述代码中,我们添加了一个isLoading的响应式变量,并将其初始值设为false。在点击按钮加载组件时,我们先将isLoading设置为true表示加载中,然后通过异步加载组件,等加载完成后,再将isLoading设置为false

总结: 在 Vue 3 中,我们可以使用defineAsyncComponent函数来定义和使用异步组件。通过使用动态import函数来异步加载组件文件,然后使用defineAsyncComponent将其包装成异步组件。在模板中,我们可以使用:is将异步组件传递给component标签来进行动态渲染。此外,我们还可以结合响应式变量来实现异步组件的加载状态展示。

顶层 await 表达式的组件

使用 <script setup> 时有顶层 await 表达式的组件会自动将组件标记为异步组件。

在 Vue 3.3.0+ 中,可以使用顶层 await 表达式来简化异步组件的使用。

vue
<script setup lang="ts">
import { ref } from "vue";
import { get } from "@/utils/http";
const users = ref([]);
const getUsers = (options = {}) => {
  return get("/api/users").then((res) => (users.value = res.data));
};
// 顶层 await 表达式会自动让该组件成为一个异步依赖
await getUsers();
</script>

<template>
  <div>
    <div>users</div>
    <div v-for="(item, index) of users">
      {{ index }} - {{ JSON.stringify(item) }}
    </div>
  </div>
</template>

在组件中,可以使用顶层 await 表达式来等待异步操作完成后再渲染组件。