美文网首页
15.异步组件和suspense

15.异步组件和suspense

作者: 静昕妈妈芦培培 | 来源:发表于2021-08-21 08:12 被阅读0次

    webpack的代码分包

    默认的打包过程:
    • 默认情况下,在构建整个组件树的过程中,因为组件和组件之间是通过模块化直接依赖的,那么webpack在打包时就会将组件模块打包到一起(比如一个app.js文件中);
    • 这个时候随着项目的不断庞大,app.js文件的内容过大,会造成首屏的渲染速度变慢
    打包时,代码的分包:
    • 所以,对于一些不需要立即使用的组件,我们可以单独对它们进行拆分,拆分成一些小的代码块chunk.js;
    • 这些chunk.js会在需要时从服务器加载下来,并且运行代码,显示对应的内容;
    那么webpack中如何可以对代码进行分包呢?

    使用import函数加载模块,是异步加载;
    import函数返回一个promise

    import {
      createApp
    } from 'vue'
    import App from './10_异步组件/App.vue'
    
    //异步加载模块
    import("./utils/math").then(({sum}) => {
      console.log(sum(20, 30));
    })
    
    createApp(App).mount('#app')
    
    

    src/utils/math.js

    export function sum(a, b) {
      return  a + b
    }
    
    

    webpack在打包的时候,对于异步加载的模块,会进行分包,把其单独的打包到一个文件中


    image.png

    Vue中实现异步组件

    如果我们的项目过大了,对于某些组件我们希望通过异步的方式来进行加载(目的是可以对其进行分包处理),那么Vue中给我们提供了一个函数:defineAsyncComponent
    defineAsyncComponent函数调用返回一个异步组件

    defineAsyncComponent接受两种类型的参数:
    • 类型一:工厂函数,该工厂函数需要返回一个Promise对象;
    • 类型二:接受一个对象类型,对异步函数进行配置;
    工厂函数类型一的写法:
    <template>
      <div>
        <!--3.使用异步组件-->
         <async-about></async-about>
      </div>
    </template>
    
    <script>
    import { defineAsyncComponent } from "vue";
    //1.创建异步组件
    const AsyncAbout = defineAsyncComponent(() => import("./AsyncAbout.vue"));
    export default {
      components: {
        AsyncAbout, //2.注册异步组件
      },
    };
    </script>
    
    <style scoped></style>
    
    
    接受一个对象类型类型二写法
    <template>
      <div>
        <!--3.使用异步组件-->
         <async-about></async-about>
      </div>
    </template>
    
    <script>
    import { defineAsyncComponent } from "vue";
    import Loading from "./Loading.vue";
    import Error from "./Error.vue";
    //1.创建异步组件
    const AsyncAbout = defineAsyncComponent({
      loader: () => import("./AsyncAbout.vue"), //loder的值为一个工程函数,返回一个promise
      loadingComponent: Loading, //加载过程中显示的占位组件 占位组件不需要注册
      errorComponent: Error, //加载失败显示的占位组件
      delay: 2000, //在显示loadingComponent组件之前的延迟 | 默认值:200(单位ms)
      timeout: 5000, //加载组件的时间超过了设定值,将显示错误组件 | 默认值 Inifinity(即永不超时), 单位ms
      onError(err, retry, fail, attemps) {//监听错误事件
        console.log(err) //错误信息
        //retry 调用此函数代表尝试重新加载组件
        cnsole.log(attemps) //尝试重新加载的次数,超过次数不再加载
        //fail 调用此函数,代表加载失败,不再尝试加载了
        if(attempts <= 3) {
            retry()
        }else {
            fail()
        }
      }
    });
    export default {
      components: {
        AsyncAbout, //2.注册异步组件
      },
    };
    </script>
    
    <style scoped></style>
    

    异步组件和Suspense

    注意:目前(2021-06-08)Suspense显示的是一个实验性的特性,API随时可能会修改。

    Suspense是一个内置的全局组件,该组件有两个插槽:
    • default:如果default可以显示,那么显示default的内容;
    • fallback:如果default无法显示,那么会显示fallback插槽的内容;
    <template>
      <div>
        <suspense>
          <template #default>
            <!--3.使用异步组件-->
           <async-about></async-about>
          </template>
          <template #fallback>
            <loading></loading>
          </template>
        </suspense>
        
      </div>
    </template>
    
    <script>
    import { defineAsyncComponent } from "vue";
    //1.创建异步组件
    const AsyncAbout = defineAsyncComponent(() => import("./AsyncAbout.vue"));
    import Loading from "./Loading.vue";
    export default {
      components: {
        AsyncAbout, //2.注册异步组件
        Loading
      },
    };
    </script>
    
    <style scoped></style>
    
    

    异步组件的使用场景

    如果动态渲染的组件为同步加载的组件,webpack打包的时候,会把这些同步加载的组件,都打包到app.js中,app.js文件过大,会影响首屏加载速度
    使动态渲染的组件为异步组件,webpack打包的时候,会把各个异步组件单独打包一个文件,那些组件不会被打包到app.js中

    <template>
      <div>
        <button v-for="item in list" :key="item" 
          :class="{active: curItem === item}" 
          @click="btnClick(item)">{{item}}</button>
    
        <keep-alive include="async-about">
          <component name="why" :age="18" :is="curItem"
            @pageClick="pageClick"></component>
        </keep-alive>
    
      </div>
    </template>
    
    <script>
      import { defineAsyncComponent } from "vue";
      const AsyncAbout = defineAsyncComponent(() => import('./pages/About.vue')) 
      const AsyncHome = defineAsyncComponent(() => import('./pages/Home.vue'))
      const AsyncCategory = defineAsyncComponent(() => import('./pages/Category.vue'))
    
      export default {
        components: {
          AsyncAbout,
          AsyncHome,
          AsyncCategory
        },
        data() {
          return {
            list: ['async-home', 'async-about', 'async-category'],
            curItem: 'home'
          }
        },
        methods: {
          btnClick(item) {
            this.curItem = item
          },
          pageClick() {
            console.log('页面被点击')
          }
        }
      }
    </script>
    
    <style scoped>
      .active {
        color: red
      }
    </style>
    

    此文档主要内容来源于王红元老师的vue3+ts视频教程

    相关文章

      网友评论

          本文标题:15.异步组件和suspense

          本文链接:https://www.haomeiwen.com/subject/yzktiltx.html