前言:最近在掘金逛的时候,无意中看到前滴滴前端架构黄轶大佬,看到了大佬分享的一篇博客滴滴 webapp 5.0 Vue 2.0 重构经验分享 ,对于其中第5个问题(异步加载的业务线组件,如何动态注册?)的解决办法深为震撼。

  滴滴的首屏展示的同步业务线组件,对于一些业务线(比如顺风车,出租车,快车),这些业务线其实都可以成为单独spa应用,由于种种原因(我感觉组件化应该是很大的一个原因,构建包很小只打核心和初始化给用户显示的,剩下的业务线通过Vue异步组件注册引入)。Vue2提供的有异步注册组件

  我们注意到,官方提供的demo是异步引入本工程下的组件,对于滴滴(每个业务线是一个工程,在不同的git仓库存储)。滴滴的做法是将不同的业务线单独构建,构建的每个业务线是一个Vue实例(不知道这块是否理解有错,欢迎指正),然后将其传递给resolve函数(我感觉滴滴在这块的处理特别秒:比如全局的Vue,Vuex,公共业务组件的共享,异步业务组件的全局挂载,动态路由注册很是妙哉,希望大家去原地址查看,我这里就不赘述了)。下面是我自己的一个尝试:

  首先,在一个目录下运行 vue init webpack-simple async-component , 新建一个工程,用来开发需要异步注册的组件,在src下新建component目录,并创建index.js和async-component.vue文件,完整目录结构如下

  

  

// async-component.vue
<template>
<div class="async-component">
<h1 class="name">{{name}}</h1>
<div class="age">{{age}}</div>
</div>
</template> <script>
export default {
name: 'async-component',
data () {
return { }
},
props: {
name: {
type: String,
default: '张三'
},
age: {
type: Number,
default: 18
}
}
}
</script> <style lang="scss" scoped>
.async-component {
.name {
color: red;
}
.age {
color: green;
}
}
</style>
// index.js
/**
* Created by hs on 2019/7/15
*/
import AsyncComponent from './async-component'
if (typeof window !== 'undefined' && window.Vue) {
// 跟滴滴一样,将业务线异步组件存到window.modules下
window.modules = {
'async-component': AsyncComponent
}
}
// webpack.config.js 修改入口和出口文件
entry: process.NODE_ENV === 'development' ? './src/main.js' : './src/component/index.js',
output: {
path: path.resolve(__dirname, './dist'),
publicPath: '/dist/',
filename: 'async-component.js'
},

  在 async-component 项目根目录运行 npm run build,然后dist生成了 async-component.js 文件,然后我们进入到dist文件夹下,运行 puer (一个web服务器,如果提示没有这个命令),用npm或者yarn全局安装下,puer启动后默认地址为 http://localhost:8000 , 在浏览器测试下http://localhost:8000/async-component.js , 能成功访问即可。然后启动下我的Vue测试项目,地址为 http://localhost:8080 ,Vue测试项目代码如下:

  

// App.vue
<template>
<div id="app">
<el-button type="primary" @click="changeComponent">加载异步组件</el-button>
<component :is="componentName" name="小明" :age="50"></component>
</div>
</template> <script>
export default {
name: 'App',
data() {
return {
};
},
methods: {
changeComponent () {
this.componentName = this.name
},
loadAsyncComponent () {
Vue.component(this.name, (resolve, reject) => {
this.loadScript('http://localhost:8000/async-component.js')
.then(() => {
resolve(window.modules['async-component'])
}).catch((e) => {
reject(e)
})
})
},
loadScript (url){
return new Promise((resolve, reject) => {
var script = document.createElement ("script")
script.type = "text/javascript";
if (script.readyState){ //IE
script.onreadystatechange = function(){
if (script.readyState == "loaded" || script.readyState == "complete"){
script.onreadystatechange = null;
resolve()
}
};
} else { //Others
script.onload = function(){
console.log('complete')
resolve()
};
script.onerror = function (e) {
reject(e)
}
}
script.src = url;
document.getElementsByTagName("body")[0].appendChild(script);
})
}
},
mounted() {
this.loadAsyncComponent()
} }
</script> <style lang="scss">
* {
margin: 0;
padding: 0;
font-family: Microsoft YaHei;
}
#app {
background: #f1f1f5;
}
</style>

  浏览访问 http://localhost:8080,如下

 

点击按钮后如下

  

  个人感觉滴滴这个解决方法真的很精妙,但是细细想了一下,在公司的项目中好像用不到...这个方案是滴滴结合自身业务想出来的,技术还是要结合实际项目最好。最后引用下大佬对此相关的回复:滴滴这个场景是不适合用 webpack.ensure 的,因为是动态加载其它业务线的代码,压根代码就不在一个仓库下,只能通过 loadscript 方式加载,所以也有动态注册路由的需求。技术重构往往伴随着产品重构,单纯的技术重构不太现实,除非特别闲。。所以慢慢来吧,新项目可以用 vue2 了~

  

  

Vue动态注册异步组件(非同一个工程的组件)的更多相关文章

  1. vue 动态注册路由 require.context

    需求场景: 在日常的功能练习和调试过程中,需要一个demo项目进行功能测试,由于频繁.vue页面的同时,又要再router.js文件里面注册路由,感觉有点无聊和枯燥.基于此出发点,考虑能否自动读取文件 ...

  2. Vue动态加载异步组件

    背景: 目前我们项目都是按组件划分的,然后各个组件之间封装成产品.目前都是采用iframe直接嵌套页面.项目中我们还是会碰到一些通用的组件跟业务之间有通信,这种情况下iframe并不是最好的选择,if ...

  3. Vue - 动态组件 & 异步组件

    动态组件 <div id="app"> <components :is="com[2]"></components> < ...

  4. Vue 动态组件和异步组件

    基础案例 动态组件切换类比"bilibili-个人中心"的横向菜单切换不同的标签页的功能. 在Vue中可以使用 component 标签,并加一个特殊的属性(attribute) ...

  5. Vue动态组件

    前面的话 让多个组件使用同一个挂载点,并动态切换,这就是动态组件.本文将详细介绍Vue动态组件 概述 通过使用保留的 <component> 元素,动态地绑定到它的 is 特性,可以实现动 ...

  6. 插件占坑,四大组件动态注册前奏(三) 系统BroadCast的注册发送流程

    转载请注明出处:http://blog.csdn.net/hejjunlin/article/details/52204143 前言:为什么要了解系统Activity,Service,BroadCas ...

  7. vue动态子组件的实现方式

    让多个组件使用同一个挂载点,并动态切换,这就是动态组件. 通过使用保留的 <component>元素,动态地绑定到它的 is 特性,可以实现动态组件. 方式一:局部注册所需组件 <d ...

  8. 插件占坑,四大组件动态注册前奏(二) 系统Service的启动流程

    转载请注明出处:http://blog.csdn.net/hejjunlin/article/details/52203903 前言:为什么要了解系统Activity,Service,BroadCas ...

  9. vue 动态组件

    动态组件 多个组件通过同一个挂载点进行组件的切换,is的值是哪个组件的名称,那么页面就会显示哪个组件 内置组件 (内置组件不会被渲染到页面上) component is属性     keep-aliv ...

随机推荐

  1. CSS伪元素选择器和属性选择器

    伪元素 能使用伪元素来选择元素中的一些特殊位置 一.给段落定义样式 :first-letter  首字母(只能用于块元素) :first-line  第一行 1.为p元素中的第一个字符设置颜色为黄色, ...

  2. Navicat Premuim远程连接oracle 提示 cannot load oci dll,193的解决方法

    转载:http://blog.51cto.com/xiao987334176/1640991 内网有一台windows server 2012,安装了Navicat 11.1.8 连接oracle的时 ...

  3. Parse error: syntax error, unexpected 'class' (T_CLASS)

    电脑坏了重新下载代码. 结果报错 Parse error: syntax error, unexpected 'class' (T_CLASS), expecting identifier (T_ST ...

  4. wowza 降低延迟

    转自:http://www.ttstream.com/wowza/live/howToAchieveTheLowestLatencyFromCaptureToPlayback   这篇文章介绍了在用R ...

  5. Cannot read property 'type' of undefined ....

    一直解决不了,弄了半天是 jquery 版本太低,换一个版本就ok.

  6. fedora安装ep,forge,fusion等第三方软件库

    fedora安装ep,forge,fusion等第三方软件库 官方的发行版 抛弃了有 版权争议的 软件, 特别是 包括很多第三方的 多媒体软件, 如播放 mp3, flv等的软件 解码器 这就要靠 使 ...

  7. KVM 虚拟化架构和实现原理

    目录 目录 KVM虚拟化架构 devkvm QEMU OpenstackKVMQEMU 的关系 KVM的虚拟化实现 KVM虚拟化架构 KVM是嵌入在Linux操作系统标准内核中的一个虚拟化模块,它能够 ...

  8. 【Android Studio安装部署系列】十三、Android studio添加和删除Module 2

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 概述 新建.导入.删除Module是常见的操作,这里简单介绍下. 新建Module File——New——New Module... 选中 ...

  9. C#之委托(一)

    1,什么是委托 简单来说,就是代码在恰当的时间执行一段操作.代码不需要操作的细节.举个例子,遗嘱为例.一般来说遗嘱是在某人去世之前写好,然后把它放发到一个安全的地方,去世之后然后律师会执行遗嘱中的指令 ...

  10. 【Python】Visual Studio Code 安装&&使用 hello python~~~~

    1.安装Python 官网下载: https://www.python.org/downloads/   选择版本下载 2.下载完毕后,点击安装. 3.看到页面,直接下一步,全部默认选项. 4.安装即 ...