Vue的动态组件 & 异步组件
什么是动态组件?
还是发挥一下语文阅读理解能力,动态组件,应该指的就是动态变化的组件,而不是固定写死的,不知道我的理解准不准确,来先一起看看官方的解释!
通过 标签声明一块区域,并预言这块区域将来会被某个组件通过 来填充。
这段话有点抽象,但是我们可以大胆的猜测一下,应该意思是通过 提前定义一个区块,然后注册组件的时候动态注册绑定,到底是不是这样呢?
我们还是老规矩,翠花上代码!
component-a
component-b
component-c
我们看上面的这段代码,首先声明了三个变量 、、 并为它们指定了 ,在 里面指定了 初始值为 。然后在 里面通过 声明了一块区域,并通过 绑定了 ,意为当前的 将会被 渲染。此时代码运行之后的结果为:
component-a
复制代码
以 的 替换掉了通过 声明的区域。然后通过 方法来变更 的指向,当 的指向发生改变的时候,渲染的内容也随之发生改变。
这样一种通过 来声明区域,通过来绑定组件(componentId),然后通过改变组件(componentId)指向来更改展示内容的方式就可以称为动态组件。
如果亲自运行一下上面的代码,就会发现一个问题,那就是在我们每次去切换 的时候,在浏览器的控制台中总会去弹出这么一些内容:

这表示当我们每次去切换 component 的时候,模板(component 中的 template)总会去重新渲染,而我们知道每次的 DOM 渲染其实是很消耗性能的操作,那么如果想要避免这样反复渲染的话可以通过 标签来告诉,去缓存已经被渲染过的 。
的使用非常简单,只需要使用 来包裹住 就可以了。代码如下:
复制代码
什么是异步组件?
举个生活中常见的现象来看什么是异步:你烧水,不等水烧开就去刷牙了,水烧开了会发出声音告诉你,然后你再处理水烧开之后的事情!看完这个再去理解官方的解释有点豁然开朗了!
在大型应用中,我们可能需要将应用分割成小一些的代码块,并且只在需要的时候才从服务器加载一个模块。为了简化,Vue 允许你以一个工厂函数的方式定义你的组件,这个工厂函数会异步解析你的组件定义。Vue 只有在这个组件需要被渲染的时候才会触发该工厂函数,且会把结果缓存起来供未来重渲染。
所以,由此可以看出,异步加载最重要的一个功能就是可以加快页面访问速度,比如我们可以把一些非首屏的页面做成异步加载。
定义异步组件
老规矩翠花,上代码:
我是一个异步组件
复制代码
在上面的这段代码中,首先声明了一个变量 ,并给它指定了一个 指向 ,这和声明局部组件时所进行的操作是一致的。
然后通过 来创建了一个工厂函数,这个函数包含、 两个参数。这两个参数表示两个回调方法,我们可以通过 使程序去异步加载定义的 组件,也可以使用 ('加载失败描述内容'); 来表示加载失败。这里的 仅作为模拟异步操作使用的。当然上面的代码也可以通过局部组件的方式使用:
var vm = new Vue({
el: '#app',
components: {
'async-example': function (resolve, reject) {
setTimeout(function () {
resolve(resCom);
// reject('加载失败描述内容');
}, 1000);
}
}
});
复制代码
如果大家对 Promise 比较熟悉的话,可以发现这种写法 像极了一个 的定义。在 Vue 中一样也可以通过 Promise 的方式来定义异步组件,这也是定义异步组件的第二种方式 Promise。
把上面的代码略作修改来看:
// 注册组件
var resCom = {
template: "#async-example"
};
var promise = new Promise(function(resolve, reject){
setTimeout(function(){
resolve(resCom)
}, 1000);
});
// Vue.component('async-example', function(resolve, reject){
// setTimeout(function(){
// // 向resolve回调传递组件定义
// resolve(resCom);
// }, 1000);
// });
var vm = new Vue({
el: "#app",
components:{
'async-example':function(){
return promise
}
}
})
复制代码
在上面的代码中我们声明了一个 ,具体的写法与标准方式相同,然后在注册这个异步组件时,直接 回这个 即可。
我们在前面说过是 Vue 所推崇的一种构建方式,同时 Webpack 也直接内建支持这种 Promise 的异步组件注册方式。当使用 Webpack 来构建正式项目时,我们也可以直接通过 来注册一个异步组件, 会直接返回一个 Promise。
// 全局注册
Vue.component(
'async-webpack-example',
// 这个 `import` 函数会返回一个 `Promise` 对象。
() => import('./my-async-component')
)
// 局部注册
new Vue({
// ...
components: {
'my-component': () => import('./my-async-component')
}
})
复制代码
最后一种异步注册的方式,我们称它为高级异步组件,这种方式是在 Vue2.3.0 新增的一种异步组件注册方式。看一下高级异步组件应该如何定义:
复制代码
可以看到高级异步组件的配置更加全面,在逻辑上反而会比前两种异步组件的配置方式更加简单,所以在实际的项目使用中,我们也更加推崇使用高级异步组件的方式来定义异步组件。