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

导读:本篇文章讲解 vue 异步加载全局组件 Vue.component(String, Object),希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

一.举例场景

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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之家整理,本文链接:https://www.bmabk.com/index.php/post/17165.html

(0)
小半的头像小半

相关推荐

极客之家——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!