15.异步组件和suspense

2021-08-21  本文已影响0人  静昕妈妈芦培培

webpack的代码分包

默认的打包过程:
打包时,代码的分包:
那么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接受两种类型的参数:
工厂函数类型一的写法:
<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是一个内置的全局组件,该组件有两个插槽:
<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视频教程

上一篇 下一篇

猜你喜欢

热点阅读