vue按需动态异步加载组件的几种方法
这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入欢迎使用Mar
·
vue引入组件的方法一般如下
先编写两个被引入的组件
组件1:component1.vue
<template>
<div>
<h3>组件1</h3>
</div>
</template>
<script>
export default {
name: "Component1"
}
</script>
<style scoped>
</style>
组件2:component2.vue
<template>
<div>
<h3>组件2</h3>
</div>
</template>
<script>
export default {
name: "Component2"
}
</script>
<style scoped>
</style>
然后组件中引入以上组件
<template>
<div class="container">
<component1/>
<component2/>
</div>
</template>
<script>
import Component1 from "component1.vue";
import Component2 from "component2.vue";
export default {
name: "content1",
components: {Component1,Component2},
}
</script>
以上方式使用静态import的方式引入组件,无法灵活的按需引入组件,最多控制显示哪个。
我总结了几种按需动态加载组件的方法,vue版本2.6.11
方法一
通过动态修改components内组件指向的方式实现异步动态加载组件
<template>
<div class="wrapper">
<h3 style="text-align: left">ComponentsMode</h3>
<button @click="show = false">销毁</button>
<button @click="switchComponent('component1')">组件1</button>
<button @click="switchComponent('component2')">组件2</button>
<div class="a">
<model-page v-if="show"></model-page>
</div>
</div>
</template>
<script>
import Component1 from "component1";
export default {
name: "AsyncComponent",
components: {
/*
* 这里使用import()实现异步加载组件, 而且component可以改成变量, 但正常注册组件的行为只会执行一次,
* 即使component的值改变, 或者本组件重新加载, 也无法重新注册组件, 所以这里只能实现延迟加载组件的的功能
* 可以使用折中方法,给组件套个父级,通过销毁和创建父级的方法重新注册组件,实现动态组件功能,不再赘述
* */
ModelPage: () => {
let component = 'component1';
/*import()本身支持变量, 但一方面许多浏览器对import()支持不佳, 另一方面, 项目需要使用webpack编译, 使用变量webpack无法判断哪些文件需要编译
而且微博pack编译打包后, js文件被打包到app.js, 浏览器不可能只加载一个文件的一部分, 这时单独import毫无意义,
webpack提供了解决方法, import的路径仅文件名使用变量, 目录路径使用常量, webpack编译打包时会把该路径下所有js单独打包, 而不是合并到app.js
* */
return import(`./${component}`);
}
},
data() {
return {
show: false,
apps: null,
}
},
methods: {
/*
* 通过动态修改$options的components内的组件实现动态异步加载组件的功能
* */
switchComponent: function (component) {
this.$options.components['ModelPage'] = () => import(`./${component}`);
//由于components改变后视图不会自动刷新, 需要手动刷新, 也可以使用this.$forceUpdate()
this.show = false;
let that = this;
this.$nextTick(() => {
that.show = true;
})
}
},
}
</script>
<style scoped>
.wrapper {
padding: 15px;
}
.a {
text-align: left;
height: 100px;
border: 1px solid blue;
margin-top: 20px;
}
</style>
方法二
使用Vue.extend实现异步加载组件
这种方式生成的vue实例虽然可以通过propsData传参, 但实例没有parent, 没有上下文, 但不能实现双向绑定, 可以通过直接调用实例方法或者实例事件的方式通讯
<template>
<div class="wrapper">
<h3 style="text-align:left;">extendMode</h3>
<button @click="switchComponent('component1')">组件1</button>
<button @click="switchComponent('component2')">组件2</button>
<div class="a">
<div id="mount-point" ref="mount-point"></div>
</div>
</div>
</template>
<script>
import Vue from 'vue';
export default {
name: "ExtendMode",
data(){
return {
instance: null
}
},
methods: {
switchComponent: function (name) {
if(this.instance){
this.instance.$destroy();
this.$refs['mount-point'].removeChild(this.instance.$el);
}
import(`./${name}`).then(component => {
let VueConstructor = Vue.extend(component.default); //使用Vue.extend创建组件构造器
this.instance = new VueConstructor();
this.instance.$mount();
this.$refs['mount-point'].appendChild(this.instance.$el);//挂载到指定dom上
});
}
}
}
</script>
<style scoped>
.wrapper {
padding: 15px;
}
.a {
text-align: left;
height: 100px;
border: 1px solid blue;
margin-top: 20px;
}
</style>
方法三
通过特殊 attribute is实现动态异步加载组件功能
is的值可以是组件命名, 也可以是组件选项对象, 这里使用的是后者, 使用动态修改is指向的组件选项对象, 实现动态异步加载组件
<template>
<div class="wrapper">
<h3 style="text-align: left">IsMode</h3>
<button @click="show = false">销毁</button>
<button @click="switchComponent('component1')">组件1</button>
<button @click="switchComponent('component2')">组件2</button>
<div class="a">
<component :is="apps" v-if="show"></component>
</div>
</div>
</template>
<script>
export default {
name: "IsMode",
data() {
return {
show: false,
apps: null,
}
},
methods: {
switchComponent: function (component) {
this.apps = () => import(`./${component}`);
this.show = true;
}
},
}
</script>
<style scoped>
.wrapper {
padding: 15px;
}
.a {
text-align: left;
height: 100px;
border: 1px solid blue;
margin-top: 20px;
}
</style>
方法四
和方法三类似, 只不过使用的是全局组件注册方式实现
<template>
<div class="wrapper">
<h3 style="text-align:left;">VueComponentMode</h3>
<button @click="show = false">销毁</button>
<button @click="switchComponent('component1')">组件1</button>
<button @click="switchComponent('component2')">组件2</button>
<div class="a">
<component :is="apps" v-if="show"></component>
</div>
</div>
</template>
<script>
import Vue from 'vue';
export default {
name: "VueComponent",
data() {
return {
show: false,
apps: 'ModelPage',
}
},
methods: {
/*
* 通过动态注册全局组件实现动态异步加载组件的功能
* */
switchComponent: function (component) {
Vue.component('ModelPage', () => import(`./${component}`));
//由于components改变后视图不会自动刷新, 需要手动刷新, 也可以使用this.$forceUpdate()
this.show = false;
let that = this;
window.setTimeout(function () {
that.show = true;
})
}
}
}
</script>
<style scoped>
.wrapper {
padding: 15px;
}
.a {
text-align: left;
height: 100px;
border: 1px solid blue;
margin-top: 20px;
}
</style>
更多推荐
已为社区贡献2条内容
所有评论(0)