12 vue3之异步组件&代码分包&内置组件suspense和teleport

异步组件

在大型应用中,我们可能需要将应用分割成小一些的代码块 并且减少主包的体积(不需要在首屏加载得都可使用异步组件)

这时候就可以使用异步组件

顶层 await

在setup语法糖里面 使用方法

<script setup> 中可以使用顶层 await。结果代码会被编译成 async setup()

<script setup>
const post = await fetch(`/api/post/1`).then(r => r.json())
</script>

父组件引用子组件 通过defineAsyncComponent加载异步配合import 函数模式便可以分包

<script setup lang="ts">
import { reactive, ref, markRaw, toRaw, defineAsyncComponent } from 'vue'
 
const Dialog = defineAsyncComponent(() => import('../../components/Dialog/index.vue'))
 
//完整写法
 
const AsyncComp = defineAsyncComponent({
  // 加载函数
  loader: () => import('./Foo.vue'),
 
  // 加载异步组件时使用的组件
  loadingComponent: LoadingComponent,
  // 展示加载组件前的延迟时间,默认为 200ms
  delay: 200,
 
  // 加载失败后展示的组件
  errorComponent: ErrorComponent,
  // 如果提供了一个 timeout 时间限制,并超时了
  // 也会显示这里配置的报错组件,默认值是:Infinity
  timeout: 3000
})

内置组件suspense

<suspense> 组件有两个插槽。它们都只接收一个直接子节点。default 插槽里的节点会尽可能展示出来。如果不能,则展示 fallback 插槽里的节点。

     <Suspense>
            <template #default>
                <Dialog>
                    <template #default>
                        <div>我在哪儿</div>
                    </template>
                </Dialog>
            </template>
 
            <template #fallback>
                <div>loading...</div>
            </template>
        </Suspense>

 代码案例

父组件

<template>
  <div class=""></div>
  <suspense>
    <template #default>
      <Eleven></Eleven>
    </template>
    <template #fallback>
      <div>loading.....也可使用骨架屏代替</div>
    </template>
  </suspense>
</template>

<script setup lang="ts">
import { ref, reactive, defineAsyncComponent } from "vue";
// import Eleven from "./components/eleven.vue";
const Eleven = defineAsyncComponent(
  () => import("./components/eleven.vue")
);
</script>

<style lang="less" scoped></style>

 eleven.vue

<template>
  <div class="" v-for="(iten, index) in data" :key="index">
    {{ iten?.name }}
  </div>
</template>

<script setup lang="ts">
import { ref, reactive } from "vue";
import { axiosXhr } from "./eleven_server";
let data = await axiosXhr("./data.json");
console.log(data);
</script>

<style lang="less" scoped></style>

 eleven_server.ts

export const axiosXhr = (url: string) => {
  return new Promise((resolve) => {
    let xhr = new XMLHttpRequest();
    xhr.open("GET", url);
    xhr.onreadystatechange = () => {
      console.log(xhr);
      if (xhr.readyState === 4 && xhr.status === 200) {
        setTimeout(() => {
          resolve(JSON.parse(xhr.responseText));
        }, 2000);
      }
    };
    xhr.send();
  });
};

 data.json

[
  {
    "name": "cookie1"
  },
  {
    "name": "cookie2"
  }
]

效果图:

先加载fallback节点文本,2s后再加载匿名插槽节点

 内置组件teleport

Teleport Vue 3.0新特性之一。

Teleport 是一种能够将我们的模板渲染至指定DOM节点,不受父级style、v-show等属性影响,但data、prop数据依旧能够共用的技术;类似于 React 的 Portal。

主要解决的问题 因为Teleport节点挂载在其他指定的DOM节点下,完全不受父级style样式影响

使用方法
通过to 属性 插入指定元素位置 to="body" 便可以将Teleport 内容传送到指定位置

<Teleport to="body">
    <Loading></Loading>
</Teleport>

动态控制teleport

使用disabled 设置为 true则 to属性不生效  false 则生效


    <teleport :disabled="true" to='body'>
      <A></A>
    </teleport>

代码案例

父组件:

<template>
  <div class="parent">
    <!--disabled 默认false  -->
    <teleport :disabled="false" to="body">
      <Twelve></Twelve>
    </teleport>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive } from "vue";
import Twelve from "./components/twelve.vue";
</script>

<style lang="less" scoped>
.parent {
  width: 100vw;
  height: 50vh;
  background-color: pink;
  position: relative; // 这样会改变弹窗的位置
}
</style>

 子组件twelve.vue

<template>
  <div class="dialog">弹窗</div>
</template>

<script setup lang="ts">
import { ref, reactive } from "vue";
</script>

<style lang="less" scoped>
.dialog {
  width: 200px;
  height: 200px;
  background-color: black;
  position: absolute;
  left: 50%;
  top: 50%;
}
</style>

效果图:

13 vue3之内置组件keep-alive-CSDN博客13 vue3之内置组件keep-alive。https://blog.csdn.net/qq_37550440/article/details/142386655?sharetype=blogdetail&sharerId=142386655&sharerefer=PC&sharesource=qq_37550440&spm=1011.2480.3001.8118

Vue3中,异步组件可以使用defineAsyncComponent函数进行定义。它会返回一个组件对象,可以在需要时进行动态加载。而Suspense组件则是用于处理异步组件加载时的“等待”状态,它可以显示一个自定义的“等待中”组件,直到异步组件加载完成并渲染出来。 具体来说,在使用defineAsyncComponent定义异步组件时,可以在组件选项中添加loading选项,用于指定Suspense组件中的“等待中”组件。这样,在异步组件加载完成前,Suspense组件会显示loading选项指定的组件,等异步组件加载完成后,再渲染出异步组件。 举个例子,假设我们有一个异步组件如下: ```vue <template> <div>异步组件内容</div> </template> <script> export default { name: 'AsyncComponent', // ... 异步加载组件 } </script> ``` 我们可以使用defineAsyncComponent函数来定义它,并添加loading选项: ```js import { defineAsyncComponent } from 'vue' const AsyncComponent = defineAsyncComponent({ name: 'AsyncComponent', loader: () => import('./AsyncComponent.vue'), loading: { template: '<div>加载中...</div>' } }) ``` 然后,在需要使用异步组件的地方,我们可以用Suspense组件包裹: ```vue <template> <Suspense> <template #default> <AsyncComponent /> </template> <template #fallback> <div>等待中...</div> </template> </Suspense> </template> ``` 这样,在异步组件加载完成前,Suspense组件会显示loading选项中的内容;加载完成后,就会渲染出异步组件的内容。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值