在使用 Vue.js 时按需加载组件
1

在大型应用中打包构建应用时,如果把所有的代码都打包在一起,我们的 Javascript 包可能会变得非常大,从而影响页面的加载速度。如果不是每段代码都会被所有页面用到,我们就可以将应用分割成小一些的代码块,并且只在需要的时候才从服务器加载这些代码。结合 Vue 的异步组件和 webpack 的代码分割功能,我们就能轻松实现按需加载组件。

关于异步组件

我们经常这么注册全局组件:

import Foo from './components/Foo.vue'

Vue.component('Foo', Foo)

使用上面的方式注册组件时,不管页面上有没有用到该组件,我们都需要引入 Foo.vue。Vue 允许我们以一个工厂函数的方式定义组件,这个工厂函数会异步解析组件定义,只有在组件需要被渲染的时候,该工厂函数才会被触发:

Vue.component('Foo', (resolve, reject) => {
  setTimeout(() => {
    resolve({
      template: '<div>I am async!</div>'
    })
  }, 1000)
})

工厂函数的两个参数是 Promiseresolverejectresolve 回调会在得到组件定义的时候被调用,可以使用 reject(reason) 来表示加载失败。

按需加载组件

为了将应用分割成小一些的代码块,一个推荐的做法是将异步组件和 webpack 的代码分离功能一起配合使用:

Vue.component('Foo', (resolve, reject) => {
  require(['./components/Foo.vue'], resolve)
})

上面的 require 语法会告诉 webpack,将构建代码分割成多个包,这些包会通过 Ajax 请求加载。

我们通常会在路由配置中,使用按需加载:

const router = new VueRouter({
  routes: [
    { path: '/foo', component: require(['./components/Foo.vue'], resolve) },
    { path: '/bar', component: require(['./components/Bar.vue'], resolve) }
  ]
})

使用 import()

import() 是 JavaScript 提议的一部分,用来动态地加载模块,使用它来实现按需加载:

Vue.component('Foo', () => import('./components/Foo.vue'))

使用上面的方法实现按需加载有两个前提:

  • import 函数现只是 JavaScript 提议的一部分,如果使用了 Babel,我们需要安装 syntax-dynamic-import 插件以正确地解析相关语法;
  • 需要 webpack 2 或者更高的版本,以支持使用 import 函数来定义代码分块点;

注:如果你的项目是使用 vue-cli 的 webpack 模板来搭建的,那么你可以忽略上面的两个前提,因为相关的配置都生成好了。

import 函数会返回一个 Promise 对象,我们也可以在局部注册时使用它:

components: {
  Foo: () => import('./components/Foo.vue')
}

在 Laravel 中使用 import()

在使用下面的命令创建好项目后,要使用 import(),我们还需添加对应的 Babel 插件和配置:

> composer create-project --prefer-dist laravel/laravel <project-name>

1、安装对应的 Babel 插件:

> yarn add babel-plugin-syntax-dynamic-import --dev

2、打开 webpack.mix.js 文件,添加对应的 Babel 配置:

mix.babelConfig({
  plugins: ['syntax-dynamic-import']
})

注:需要 laravel-mix 2.0 或者更高的版本,以支持使用 mix.babelConfig(),如果版本不相符,可以添加 .babelrc 文件来配置:

{
  "plugins": ["syntax-dynamic-import"]
}

推荐阅读

讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

  • 请注意单词拼写,以及中英文排版,参考此页
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`, 更多语法请见这里 Markdown 语法
  • 支持表情,使用方法请见 Emoji 自动补全来咯,可用的 Emoji 请见 :metal: :point_right: Emoji 列表 :star: :sparkles:
  • 上传图片, 支持拖拽和剪切板黏贴上传, 格式限制 - jpg, png, gif
  • 发布框支持本地存储功能,会在内容变更时保存,「提交」按钮点击时清空
  请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!