vue 异步加载全局组件 Vue.component(String, Object)

23 篇文章 0 订阅

一.举例场景

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)
  },
}

可以看到打印出来的就是一个对象
image.png
来,我们再看一下vue 官网
image.png
第二个参数传入的是一个 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 的路径,我们在浏览器直接访问这个路径就可以看到我们打包出来的代码
image.png
image.png
这就是插件管理这一块。

  • 全局挂载组件,解析我们打包出来的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}}&nbsp;&nbsp;</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进程的渲染,造成项目体验不好

image.png

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值