我们之前了解过普通组件、单文本组件,那么这篇我们将了解一下另外一种组件的声明方式——异步组件
异步组件
在大型应用中,需要加载的资源较多,导致加载时间过长,所以我们可能需要将应用分割成小一些的代码块,并且只在需要的时候才从服务器加载一个模块。
而Vue 提供的异步组件就实现了这个功能,使用 Vue 中的工厂函数的方式定义组件,这个工厂函数会异步解析你的组件定义。Vue 只有在这个组件需要被渲染时才会触发该工厂函数,且会把结果缓存起来供未来重渲染。
全局注册
<div id="app">
<div-counter>
</div-counter>
</div>
<script>
Vue.component('DivCounter', function(resolve, reject) {
setTimeout(function() {
// 向 `resolve` 回调传递组件定义
resolve({
template: '<div>我是一个全局注册的异步组件</div>'
});
}, 1000)
});
let vm = new Vue({
el: "#app",
});
</script>
这种方式是通过全局注册创建的组件,在没有调用时是不会解析的,只有在调用之后才会解析。
工厂函数有两个回调——resolve
和reject
,resolve
会在你从服务器得到组件定义的时候被调用,reject
会在加载失败的时候被调用
局部注册
<div id="app">
<div-counter2>
</div-counter2>
</div>
<script>
let vm = new Vue({
el: "#app",
components: {
'div-counter2': function(resolve, reject) {
//延时演示
setTimeout(function() {
resolve({
template: '<div>我是一个局部注册的异步组件</div>'
})
}, 1000);
}
}
});
</script>
局部注册和全局注册没有很大区别,只是注册的位置不同,使用的范围大小差异。
使用vue自带的工厂函数注册组件
<div id="app">
<div-counter>
</div-counter>
</div>
<script>
Vue.component('DivCounter', () => ({
// 需要加载的组件 (应该是一个 `Promise` 对象)
component: new Promise((reslove) => {
setTimeout(function() {
reslove({
template: '<div>我是一个全局注册的异步组件</div>'
})
}, 2000);
}),
// 异步组件加载时使用的组件
loading: {
template: '<div>我是异步组件加载时使用的组件</div>'
},
// 加载失败时使用的组件
error: {
template: '<div>我是加载失败时使用的组件</div>'
},
// 展示加载时组件的延时时间。默认值是 2000 (毫秒)
delay: 2000,
// 如果提供了超时时间且组件加载也超时了,
// 则使用加载失败时使用的组件。默认值是:`Infinity`
timeout: 3000
}));
let vm = new Vue({
el: "#app",
});
</script>
异步组件还有一种使用方式:
Vue.component(
'async-webpack-example',
// 这个动态导入会返回一个 `Promise` 对象。
() => import('./my-async-component')
)
//或者
Vue.component('async-webpack-example', function (resolve) {
// 这个特殊的 `require` 语法将会告诉 webpack
// 自动将你的构建代码切割成多个包,这些包
// 会通过 Ajax 请求加载
require(['./my-async-component'], resolve)
})
这种使用方式是将一个组件在调用的时候转化为异步调用,组件本身还是普通组件。这种方式多用于 Vue Router 中,如路由懒加载就是异步组件的使用。