一.举例场景
1.1 vue官方解释
在大型应用中,我们可能需要将应用分割成小一些的代码块,并且只在需要的时候才从服务器加载一个模块。为了简化,Vue 允许你以一个工厂函数的方式定义你的组件,这个工厂函数会异步解析你的组件定义。Vue 只有在这个组件需要被渲染的时候才会触发该工厂函数,且会把结果缓存起来供未来重渲染。
1.2 我遇到的需求
- 插件(vue组件)通过一个入口上传
- 有一个npm(我们称为渲染器)会使用
component
is
去加载,所以只能使用全局组件 - 全局组件注册只能在
new Vue()
之前
二.详解
2.1 全局组件在一个项目里面的,因为项目过大做异步加载的情况不做分析
2.2 我所遇到的情况详解
- 引入概念
import Test from '@/components/test.vue'
// 我们可以在mounted函数里面打印一下Test
export default {
name: 'app',
components: {
Test
},
mounted() {
console.log(Test)
},
}
可以看到打印出来的就是一个对象
来,我们再看一下vue 官网
第二个参数传入的是一个 Function
或者 Object
,那么重点来了,我们import导入的组件不正是一个 Object
吗,所以我们可以使用一下方式,把这个对象给存起来
- 新建一个
component.js
// 引入我们要单独打包的vue组件
import chajian from './components/zujian/mamfunc.vue'
if (typeof window !== 'undefined' && window.Vue) {
// 在运行这个组件的时候 script引入 或者 eval的时候 我们往一个数组里面push这个对象,存起来
window.chajian.push(chajian)
}
export default chajian
打包的话配置一下 webpack
这里不做介绍了,打包完之后我们会打包出来一个 mamfunc.js
这个js我们会通过一个页面上传给后台,比如一个叫 插件管理
的模块,上传之后后台会给你存储到 oss
然后返给你一个访问这个js的 http://xxx.xxx.com
的路径,我们在浏览器直接访问这个路径就可以看到我们打包出来的代码
这就是插件管理这一块。
- 全局挂载组件,解析我们打包出来的js
比如说我们可能会在另外一个项目里面取使用我们打包出来的js
<el-row :gutter="20">
<el-col
:span="colFunc(se)"
v-for="(se,index) in searchs"
:key="index"
style="margin-bottom: 12px;overflow: hidden;"
>
<p :title="se.columnComment" class="query-label">{{se.columnComment}} </p>
<div style="float:left;width:67%;margin-left: 0;">
<!--
重点就是component is属性 不明白的看一下vue官方文档对这个组件的解释
-->
<component
:ref="'searchs'+ index"
:valueCom="valueCom"
:dataInfo="se"
:is="se.type"
:searchType="'searchType'"
>
</component>
</div>
</el-col>
</el-row>
我们在这里使用 is
加载我们的组件,前提是这个组件我们已经挂载,也就是通过 Vue.component(a, {})
挂载上了,砸挂载呢,往下看…
- 请求插件列表
上面说到我们有一个插件管理,其实就是一个列表,那么会有一个 api
接口获取我们需要的插件 getPluginList
重点来了重点来了重点来了
// 发送请求获取插件列表
axios.post('/getPluginList')
// 获取到一个list
list.data.forEach(item => {
const { fileName, href } = item
Vue.component(fileName, function(resolve, reject) {
var XML = new XMLHttpRequest();
XML.open("GET", href, false);
XML.send();
if (XML.status == 200) {
// 执行以下js chajian这个数组里面就会把这个对象给push进去
eval(XML.responseText)
console.log('window.chajian: ', window.chajian)
// 重点注意一下resolve
resolve(window.chajian[window.chajian.length - 1])
}
})
})
当然也可以不异步注册,可以通过script的方式加载,但是这样会阻碍UI进程的渲染,造成项目体验不好