vue动态组件与异步组件之间的辛路历程
首先说下项目需求:单页应用中点击菜单项后动态响应页面中的tab标签(非浏览器的tab标签),tab标签对应一个页面,这将使得页面的显示由菜单主导,一般想法是点击菜单后动态显示组件,可组件怎么显示呢?
查阅vue官方文档,有个自带的动态组件
<component v-bind:is="需要动态显示的组件名"></component>
要使动态组件不随tab切换而变动(实际上每改变一次is都会new一个组件),还得加上keep-alive
<keep-alive> <component v-bind:is="需要动态显示的组件名"></component> </keep-alive>
咋一看好像需求成了,可认真一看<component>中的is需要指向已打包的组件(一般就是明确用import导入的组件),那要是组件多起来,不仅要很多import,还得在vue当前组件的components中写入好些组件映射,麻烦!最主要的是项目大起来,这么写的后果会使得webpack打包的项目体积增大,对于一个单页应用,开发者和用户都不希望看到一个页面加载太长时间吧。
接着看官方文档,后面有个新概念——异步组件,看着是个好东西,官方推荐写法:
Vue.component( '组件名', () => ({ // 需要加载的组件 (应该是一个 `Promise` 对象) component: import('组件相对路径'), // 异步组件加载时使用的组件 loading: loading, // 加载失败时使用的组件 error: error, // 展示加载时组件的延时时间。默认值是 200 (毫秒) delay: 200, // 如果提供了超时时间且组件加载也超时了, // 则使用加载失败时使用的组件。默认值是:`Infinity` timeout: 3000 }) );
马上着手并入自己的代码中,想当然的把import中的组件路径改为一个变量,加上去后编译就报错了,原来import不能这么玩,必须尽可能的明确路径。
粗略的认为,这个“异步组件”之路又不可行了,接着我考虑是否可以用ajax方式自行加载vue文件并解析呢?开始实干,接入http ajax库 axios (顺便照着网上的博文封装了一个http.js),正式加载组件,代码样本如下:
this.$http.axiosGet("./static/pages/Home2.vue") .then((result) => { var comContent = result.data; //加载获得的组件内容 Vue.component("组件名", {template: comContent}); //或者使用Vue.extend }) .catch(err => { console.log(err) } );
这下又踩坑了,一般的纯template组件,完全没问题,可vue组件文件中还有<script>代码啊,代码不执行咋办?难道我在加载完后在外部给它设置data等相关属性或函数,那加载的这块岂不是得写得非常非常非常臃肿?(这种方式我在bootstrap + jquery + vue模式中使用过,vue仅仅作为简单的数据绑定容器,全面使用vue后,肯定不能再这么干了)。
好吧,继续走在坑洼的道路上,难道就没有其它方式了?答案肯定是有的,记得我在对vue做技术评估时,初次尝试vue组件的便利,使用了一款开源组件加载器:httpVueLoader.js 按理说这也是一款神器,在不使用vuecli的情况下在简单的html文件中动态加载vue文件并能实现其中的<script>和<style>,非常了不起! 。。。。。。来转折了,但是呢,不兼容依据webpack写的组件,比如import语法,“export default” 还得改为 “module.exports=”,所有import导入组件全得改为在当前组件的依赖组件components中使用httpVueLoader加载,要是全部这么写,倒是没啥问题,要是正如vuex vueRouter呢,没这么整过,反正想着应该不够友好。如果仅仅是简单的使用vue给组件模板赋值显示,httpVueLoader.js也是一个很好的选择!
放弃 httpVueLoader.js 这条路后呢?有些人说:坚持就是胜利,就应该一条路走到黑,不过吧,毕竟写程序需要理智,不能脑袋抽风!虽然走了三条路,三条路都被我一一排查、验证和否定,但……,就没有我疏漏的地方?我再次反复观看官方文档,既然官方推荐这样做,肯定是有道理的,那么,又回到我走过的第一条路吧。
既然import不能使用变量是因为import中必须尽可能的明确组件路径地址这条硬性限制,我是否可以将import中的内容改为 "组件路径”+组件名的方式呢,经过验证,是可行的,最终用法如下:
Vue.component( comName, () => ({ //import应该尽可能的缩小path范围,不然会出错 component: import('../../static/pages/' + comName), loading: asynLoading, error: asynError, delay: 200, timeout: 3000 }) );
解决!
再次,感谢 https://m.jb51.net/article/143925.html 这篇博文作者对webpack import做了细致分析!

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Spring 源码(九)@Autowired注解实现原理(Spring Bean的自动装配)
@Autowired注解的实现过程,其实就是Spring Bean的自动装配过程。通过看@Autowired源码注释部分我们可以看到@Autowired的实现是通过AutowiredAnnotationBeanPostProcessor后置处理器中实现的。 AutowiredAnnotationBeanPostProcessor 类图 PriorityOrdered:确认 AutowiredAnnotationBeanPostProcessor 后置处理器的执行优先级 BeanFactoryAware:使得AutowiredAnnotationBeanPostProcessor 可以直接通过BeanFactory获取容器中的Bean BeanPostProcessor:在 Bean 初始化前后执行的后置处理器 InstantiationAwareBeanPostProcessor:在 Bean 实例化前后和Bean设置属性值时执行的后置处理器 SmartInstantiationAwareBeanPostProcessor:智能实例化Bean的后处理器,如预测Bean的类型和确认Bea...
- 下一篇
RocketMQ主从同步若干问题答疑
1、初识主从同步 主从同步基本实现过程如下图所示: RocketMQ 的主从同步机制如下: 首先启动Master并在指定端口监听; 客户端启动,主动连接Master,建立TCP连接; 客户端以每隔5s的间隔时间向服务端拉取消息,如果是第一次拉取的话,先获取本地commitlog文件中最大的偏移量,以该偏移量向服务端拉取消息; 服务端解析请求,并返回一批数据给客户端; 客户端收到一批消息后,将消息写入本地commitlog文件中,然后向Master汇报拉取进度,并更新下一次待拉取偏移量; 然后重复第3步; RocketMQ主从同步一个重要的特征:主从同步不具备主从切换功能,即当主节点宕机后,从不会接管消息发送,但可以提供消息读取。 > 温馨提示:本文并不会详细分析RocketMQ主从同步的实现细节,如大家对其感兴趣,可以查阅笔者所著的《RocketMQ技术内幕》或查看笔者博文:RocketMQ主从同步详解 2、提出问题 主,从服务器都在运行过程中,消息消费者是从主拉取消息还是从从拉取? RocketMQ主从同步架构中,如果主服务器宕机,从服务器会接管消息消费,此时消息消费进度如何保...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS8安装Docker,最新的服务器搭配容器使用
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- Hadoop3单机部署,实现最简伪集群
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- Linux系统CentOS6、CentOS7手动修改IP地址
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Windows10,CentOS7,CentOS8安装Nodejs环境
- 设置Eclipse缩进为4个空格,增强代码规范
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题