手机版

Vue动态加载异步组件的方法

时间:2021-08-28 来源:互联网 编辑:宝哥软件园 浏览:

背景:

目前我们的项目都是按组件划分,然后把每个组件打包成产品。目前,iframe用于直接嵌套页面。在项目中,我们仍然会遇到一些与服务通信的常见组件。在这种情况下,iframe不是最佳选择,iframe存在跨域问题。postMessage仍然可以交流,但不是最好的。目前有这样一个场景:门户需要制作一个通用的首页和数据概览页面,首页和数据概览页面通过小部件自由拼接。在制作业务组件时,只需要提供每个模块小部件的url,但是如果小部件之间仍然有连接呢?那么iframe就不好了。目前使用Vue动态加载异步组件,实现小组件之间的通信。当然,门户还应该提供一个通信基线:Vue事件总线(空的Vue实例对象)。

内容:

任何使用过vue的人都应该知道vue的动态加载组件:

Vue绑定要通过is加载的组件。所以我们现在需要的是如何封装组件。如果我们复制业务组件内部的代码,我们需要找到所有的依赖项,并将其复制过去(在许多情况下,一些图片或css会被省略)。这种方法成本相对较低,维护也不方便。因此,我们需要通过webpack将单个vue文件打包到js中。这里,一个vue被打包成一个js,没有代码分割和css分离。因为加载组件时只需要加载一个文件。包文件配置如下:

首先将package命令添加到package.json:

脚本' : { . '构建CMP' : '节点构建/构建-组件. js'},构建-组件. js文件:

请使用严格的“require”。/check-versions())process . ENV . NODE _ ENV=' production ' const ora=require(' ora ')const path=require(' path ')const粉笔=require('粉笔')const web pack=require(' web pack ')const web pack config=require('。/web pack . out-components . prod . conf ')const spinner=ora('为sync-components构建.')spinner . start()web pack(webpackConfig,function (err,stats){ spinner . stop()if(err)throw err process . stdout . write(stats . tostring)({ colors : true,modules: false,children: false,chunk s 3360 false })' \ n \ n ')if(stats . haserrors()){ console . log(粉笔. red(' Build失败并出现错误。\ n ')进程。退出(1) }控制台。日志(粉笔。青色('构建完成。\ n ')控制台.日志(粉笔.黄色(' Tip:构建的文件应该通过HTTP服务器提供。\n ' '通过文件:打开index.html//\不起作用。\ n '))})web pack . out-components . prod . conf . js文件的配置如下

const web pack=require(' web pack ');const path=require(' path ');const utils=require(' ./utils ');const OptimizeCSSPlugin=require(' optimize-CSS-assets-web pack-plugin ')const { entry,mkdirsSync}=require(' ./out-组件-工具')函数解析(目录){ 0返回路径。join(__dirname,'.',dir)} mkdirsSync(resolve('/static/outComponents ')模块。exports={ entry: entry,output : { path : resolve('/static/outComponents '),filename: '[name]' .js ',},解析: {扩展名s 3360[' .js ',' .呜呜呜.json'],别名: { ' vue $ ' : ' vue/dist/vue。无害环境管理。js ',' @': resolve('src ',} }),externals: { vue: 'vue ',axios: ' axios ' },模块: { rules 3360[{ test :/\ .vue$/,loader: 'vue-loader ',options : { es module : false,//vue-loader v13更新默认值为真v12及之前版本为假的,此项配置影响某视频剪辑软件自身异步组件写法以及工具打包结果装载机:实用程序。CSS加载器({源映射: true,提取: false //css不做提取}),transform to require : { video : ' src ',source: 'src ',img: 'src ',image: 'xlink:href' } } },{ test: /\ .js$/,loader: 'babel-loader ',包含: [resolve('src '),resolve('test')] },{ test: /\ .(png|jpe?g|gif|svg)(\?*)?$/,loader: 'url-loader ',options: { limit: 10000,name : utils。资产路径(' img/[name]).[hash:7].[ext]') },{ test: /\ .(MP4 | webm | ogg | MP3 | wav | FLAC | AAC)(\?*)?$/,loader: 'url-loader ',options: { limit: 10000,name : utils。资产路径('媒体/[名称]).[hash:7].[ext]') },{ test: /\ .(woff2?|eot|ttf|otf)(\?*)?$/,loader: 'url-loader ',options: { limit: 10000,name : utils。资产路径(' font/[name]).[hash:7].[ext]') } } ] },plugins: [新网络包.definepreplugin({ ' process。ENV。node _ ENV ' : ' ' production ' ' }),//UglifyJs不支持ES6,您也可以使用巴别尔-米尼菲获得更好的树摇: https://github.com/babel/minify新网络包。优化。uglifyjsplugin({ compression : false,sourceMap: true }),//compresse提取的CSS .我们正在使用这个插件,以便可以对来自不同组件的可能//重复的半铸钢钢性铸铁(Cast Semi-Steel)进行重复数据删除new OptimizeCSSPlugin({ csprocessor options 3360 { safe : true } })]};组件外工具文件配置如下:

const glob=require(' glob ')const fs=require(' fs ');const path=require(' path ');//遍历要打包的组件let entry={ } var modules carray=glob。同步(' ./src/out-组件/*)用于(模块carray中的var x){ 0让fileName=(模块carray[x]).拆分('/')[3]).切片(0,-4)条目[FIlename]=module array[x]}//清理文件函数mkdirsSync(dirname){ if(fs。existssync(dirname)){全部删除(dirname)返回true} else { if(mkdirsSync)(路径。dirname(dirname))){ fs。mkdirsync(dirname);返回真;} }}//删除文件下的文件函数删除所有(路径){ var files=[];if(fs.existsSync(路径)){ files=fs.readdirSync(路径);files.forEach(函数(文件,索引){ var curPath=path/'文件;if(fs.statSync(curPath)).isDirectory()){//recurse delete all(curPath);} else { //删除文件fs。取消同步链接(CurPath);} });}};出口。entry=entryexports。mkdirssync=mkdirssync构建组件是打包的入口文件,网络包。组件外。产品。糖膏剂射流研究…是工具打包的配置文件组件外工具是工具库,这边是打包的进入自动获取(默认为src/输出组件),还有自动删除之前打包的文件。

目前的文件目录为

通过打包生产文件:

在静电下外部组件文件夹内的射流研究…文件。(最终打包需要打包到距离下面,这边做测试先打包在静电文件下,方便后续动态组件创建交互式、快速动态网页应用的网页开发技术获取组件使用)

门户小部件是通过配置url和调整布局产生的。因此,业务组件到目前为止已经完成。只需提供门户公开的url。接下来是在门户端加载动态组件的实现。门户相对简单。配置见下图:

门户通过组件的动态组件加载异步组件,通过ajax请求刚刚打包的url,然后实例化函数new Function将其赋给mode(new Function之所以分为两部分,是验证规则的问题,可以忽略)。这使得动态加载异步组件成为可能。门户和业务组件可以分开开发。对于任何业务开发数据的概述,门户不需要更改代码,只需要在界面上配置url。这个异步加载组件结束了。这里的门户需要封装一个实现异步的组件。家长只需要传入网址。这里可以优化的另一点是,可以先缓存模式,所以不需要每次都加载请求。如下所示:

我们可以看到在门户的一个数据概览页面上加载了很多异步组件,所以异步组件之间可能会有通信,那么我们应该怎么做呢?因为iframe不再嵌套,可以通过监听一个组件来调用另一个组件的方法,这样确实可以实现同级别组件之间的通信,但这绝对是不可取的,因为一旦这样做,门户必须根据业务进行辅助,修改代码才能实现功能。因此,我们使用portal来生成vue事件总线(空vue实例)。

门户代码如下:在上面挂一个事件总线。$root:

created () { if(!这个。$ root。{这个。$ root。eventbus=newvue ()}}然后业务组件可以根据自己的业务进行通信:

组件1和组件2的代码如下:

模板div class='test1 '这是一个外部组件a1 hello-word/hello-word/div/模板脚本导入helloword来自'./components/hello world ' export default { data(){ return { I : 0 } },components: { helloWord },mounted(){ setInterval(()={ this . I if(this . I 10){ this . test()},1000) },methods: { test () { this。$ root . event bus . $ emit(' child event ',这。I)} } }/脚本模板div class=' test1 '这也是一个外部组件。Div这是{ { a1 } }/Div/div/模板脚本从A1导出默认{ data }(返回{ a1: 0 } },创建的(){ this。$root.eventBus.$on('childEvent ',this.change) },methods : { change(I){ this . a1=I } }/script业务组件可以根据此进行相互通信。vue上的$root.eventBus和事件传输($emit,$on)。

总结:本文借助vue的动态组件和webpack打包的单个文件动态加载异步组件,并在此基础上挂载vue的事件总线实现并行组件之间的通信。$root。

扩展方向:这种方法不仅可以应用于门户单个页面上的小部件,而且如果项目中的页面文件需要重用,他们不想复制代码,也可以在该文件中配置打包的单个文件,打包的文件可以在项目中动态加载。这种模式类似于普通组件的安装模式,只是这种单文件vue不常见,但也可以到达打包重用页面。

以上就是本文的全部内容。希望对大家的学习有帮助,支持我们。

版权声明:Vue动态加载异步组件的方法是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。