首页 > 其他分享 >第二十七篇 vue - 深入组件 - 内置组件 - Suspense

第二十七篇 vue - 深入组件 - 内置组件 - Suspense

时间:2023-04-01 11:58:44浏览次数:49  
标签:异步 vue 状态 插槽 依赖 Suspense 组件 加载

Suspense

<Suspense> 是一个内置组件,用来在组件树中协调对异步依赖的处理。它让我们可以在组件树上层等待下层的多个嵌套异步依赖项解析完成,并可以在等待时渲染一个加载状态

<Suspense> 是一项实验性功能。它不一定会最终成为稳定功能,并且在稳定之前相关 API 也可能会发生变化

异步依赖

要了解 <Suspense> 所解决的问题和它是如何与异步依赖进行交互的,我们需要想象这样一种组件层级结构

<Suspense>
└─ <Dashboard>
   ├─ <Profile>
   │  └─ <FriendStatus>(组件有异步的 setup())
   └─ <Content>
      ├─ <ActivityFeed> (异步组件)
      └─ <Stats>(异步组件)
      
在这个组件树中有多个嵌套组件,要渲染出它们,首先得解析一些异步资源。如果没有 <Suspense>,则它们每个都需要处理自己的加载、报错和完成状态。在最坏的情况下,我们可能会在页面上看到三个旋转的加载态,在不同的时间显示出内容。

有了 <Suspense> 组件后,我们就可以在等待整个多层级组件树中的各个异步依赖获取结果时,在顶层展示出加载中或加载失败的状态。      
<Suspense> 可以等待的异步依赖有两种:

  1、带有异步 setup() 钩子的组件。这也包含了使用 <script setup> 时有顶层 await 表达式的组件。

  2、异步组件。
async setup()
组合式 API 中组件的 setup() 钩子可以是异步的:

export default {
  async setup() {
    const res = await fetch(...)
    const posts = await res.json()
    return {
      posts
    }
  }
}

如果使用 <script setup>,那么顶层 await 表达式会自动让该组件成为一个异步依赖

<script setup>
const res = await fetch(...)
const posts = await res.json()
</script>

<template>
  {{ posts }}
</template>
异步组件
异步组件默认就是“suspensible”的。这意味着如果组件关系链上有一个 <Suspense>,那么这个异步组件就会被当作这个 <Suspense> 的一个异步依赖。在这种情况下,加载状态是由 <Suspense> 控制,而该组件自己的加载、报错、延时和超时等选项都将被忽略。

异步组件也可以通过在选项中指定 suspensible: false 表明不用 Suspense 控制,并让组件始终自己控制其加载状态
加载中状态

<Suspense> 组件有两个插槽:#default 和 #fallback。两个插槽都只允许一个直接子节点。在可能的时候都将显示默认槽中的节点。否则将显示后备槽中的节点

<Suspense>
  <!-- 具有深层异步依赖的组件 -->
  <Dashboard />

  <!-- 在 #fallback 插槽中显示 “正在加载中” -->
  <template #fallback>
    Loading...
  </template>
</Suspense>
在初始渲染时,<Suspense> 将在内存中渲染其默认的插槽内容。如果在这个过程中遇到任何异步依赖,则会进入挂起状态。在挂起状态期间,展示的是后备内容。当所有遇到的异步依赖都完成后,<Suspense> 会进入完成状态,并将展示出默认插槽的内容。

如果在初次渲染时没有遇到异步依赖,<Suspense> 会直接进入完成状态。

进入完成状态后,只有当默认插槽的根节点被替换时,<Suspense> 才会回到挂起状态。组件树中新的更深层次的异步依赖不会造成 <Suspense> 回退到挂起状态。

发生回退时,后备内容不会立即展示出来。相反,<Suspense> 在等待新内容和异步依赖完成时,会展示之前 #default 插槽的内容。这个行为可以通过一个 timeout prop 进行配置:在等待渲染新内容耗时超过 timeout 之后,<Suspense> 将会切换为展示后备内容。若 timeout 值为 0 将导致在替换默认内容时立即显示后备内容
事件
<Suspense> 组件会触发三个事件:pending、resolve 和 fallback。pending 事件是在进入挂起状态时触发。resolve 事件是在 default 插槽完成获取新内容时触发。fallback 事件则是在 fallback 插槽的内容显示时触发。

例如,可以使用这些事件在加载新组件时在之前的 DOM 最上层显示一个加载指示器
错误处理
<Suspense> 组件自身目前还不提供错误处理,不过你可以使用 errorCaptured 选项或者 one rrorCaptured() 钩子,在使用到 <Suspense> 的父组件中捕获和处理异步错误
和其他组件结合
我们常常会将 <Suspense> 和 <Transition>、<KeepAlive> 等组件结合。要保证这些组件都能正常工作,嵌套的顺序非常重要。

另外,这些组件都通常与 Vue Router 中的 <RouterView> 组件结合使用。

下面的示例展示了如何嵌套这些组件,使它们都能按照预期的方式运行。若想组合得更简单,你也可以删除一些你不需要的组件:

<RouterView v-slot="{ Component }">
  <template v-if="Component">
    <Transition mode="out-in">
      <KeepAlive>
        <Suspense>
          <!-- 主要内容 -->
          <component :is="Component"></component>

          <!-- 加载中状态 -->
          <template #fallback>
            正在加载...
          </template>
        </Suspense>
      </KeepAlive>
    </Transition>
  </template>
</RouterView>

Vue Router 使用动态导入对懒加载组件进行了内置支持。这些与异步组件不同,目前他们不会触发 <Suspense>。但是,它们仍然可以有异步组件作为后代,这些组件可以照常触发 <Suspense>

标签:异步,vue,状态,插槽,依赖,Suspense,组件,加载
From: https://www.cnblogs.com/caix-1987/p/17278343.html

相关文章

  • 第二十六篇 vue - 深入组件 - 内置组件 - Teleport
    Teleport<Teleport>是一个内置组件,它可以将一个组件内部的一部分模板“传送”到该组件的DOM结构外层的位置去基本用法有时我们可能会遇到这样的场景:一个组件模板的一部分在逻辑上从属于该组件,但从整个应用视图的角度来看,它在DOM中应该被渲染在整个Vue应用外部的其他地方......
  • 第二十八篇 vue - 深入组件 - 动态组件 - component
    component动态组件就是动态变化的组件,和动态样式一样,通过用户的操作来确定是什么类型的组件。动态样式是绑定:style,动态组件则是绑定:is在vue中,实现Tab切换主要有三种方式:使用动态组件,使用vue-router路由,使用第三方插件。本文将详细介绍Vue动态组件所谓动态组件就是让多......
  • [vue3]npm创建环境
    1.npm安装vuecli[root@Python20230401VUE3]#npminstall-g@vue/cli2.查看vue版本[root@Python20230401VUE3]#vue--version@vue/cli5.0.83.创建项目[root@Python20230401VUE3]#vuecreatehello-world4.执行项目$cdhello-world$npmrunserve......
  • 第二十一篇 vue - 深入组件 - 依赖注入 - provide 和 inject
    Prop逐级透传问题provide和inject可以帮助我们解决这一问题。[1]一个父组件相对于其所有的后代组件,会作为依赖提供者任何后代的组件树,无论层级有多深,都可以注入由父组件提供给整条链路的依赖Prop逐级透传问题通常情况下,当我们需要从父组件向子组件传递数据时,会使用pr......
  • vue2 + sass + sass-loader
    本地vue脚手架版本:5.0.8本地node版本:v18.13.0项目创建:vueinitwebpackdemo由于项目本身不支持sass,需要首先安装:npminstallsasssass-loader-D,记住:此处无需安装node-sass,安装后报错。由于sass和sass-loader版本不兼容会出现报错(TypeError:this.getOptionsisnotafunc......
  • vue (一)
     vue是一套构建用户界面的前端框架。 构建用户界面指的是用vue往html中填充数据。 框架指的是一套现成的解决方案,程序员只能遵守框架的规范,去编写自己的业务功能。 vue指令、组件(ui的复用)、路由、vuex、vue组件库 只有把上面罗列的内容掌握之后才有开发vue项目的能力。......
  • VUE分别使用普通方法、计算属性、监听器完成简易计算器
    VUE分别使用普通方法、计算属性、监听器完成简易计算器声明:本方法使用VUE完整框架独立模块组件来实现TOP:实现效果Ⅰ:完整框架Ⅱ:框架实现案例组件功能细分1.APP组件总组件,管理所有组件(每个单独的组件最后都汇总到APP组件里,便于管理)管理汇总:Methodss组件、Watchss......
  • process.env.NODE_ENV 开发环境配置详解(Vue项目)
    开发环境与生产环境下切换baseURL增加.env.development文件NODE_ENV='development'VUE_APP_BASE_URL='/api'增加.env.development文件NODE_ENV='production'VUE_APP_BASE_URL=''使用constaxiosRequest=axios.create({base......
  • 我的第一个项目(七):(解决问题)Vue中canvas无法绘制图片
    好家伙, 现在,我想要把我的飞机大战塞到我的主页里去,想办法把文件导入 然后,直接死在第一步,图片渲染都成问题 先用vue写一个测试文件来测试canvas的绘制<template><div><divref="stage"></div><button@click="drawsth()">添加</button><imgsrc......
  • Vue 2中实现数字滚动效果
     代码:<template><divclass="statistics-num"><!--显示当前数字,不使用逗号分隔符--><spanclass="num">{{currentVal.toString()}}</span><!--显示当前数字,用逗号分隔符--><!--<spanclass="num......