在使用开源的地图框架在网页上搭建地图的时候,我就一直有过一个想法,那就是如何将它们封装成类似UI框架类似的组件,后面发现这其实是一个VUE3生命周期执行顺序的问题,下面是以地图为例子进行解析。
地图加载矢量图形的方式
在很多的地图框架不管是有比较详细中文文档的高德百度地图,还是国外开源的openlayers、cesium、mapbox gl。他们想要画一个矢量的方式都脱离不了地图-图层-数据源这样一层关系。而如果要以组件的方式去表达这样的一个关系展现出来的形式,那就会是
<map> //地图
<layer> // 图层
<source/> // 数据源
</layer>
</map>
但是在vue3中生命周期中,优先加载完整个组件是最里面的子组件,这就造成了一个问题,加载顺序的问题,有的地图框架是加载完地图之后才可以继续加载图层和数据源,但是如果按VUE3的生命周期,那就会造成地图对象没生成的情况。所以如果遇到这种情况,最简单的实现方式就是给地图组件的插槽添加v-if控制加载顺序。
map组件
<div>
<slot v-if="maplogin"><slot/> //maplogin初始值为false,地图对象创建完毕之后更改为true
<div>
然后通过依赖注入也就是Provide / Inject去给图层组件和数据源组件传递map对象值,让他们进行创建数据源和图层。
同理如果数据源如果是建立在图层先建立好的情况下也可以这样进行操作,但如果没有的话就不用这样操作。
到这里我们又遇到一个问题,如果数据源组件发生变动,想要将数值传递给图层组件,或者数据源组件是多个图层通用一个数据源(就是数据源组件不放在图层组件的插槽里放在地图组件的插槽里),这个时候就需要用到mitt。
Mitt是一个简洁、灵活的JavaScript事件订阅和发布库。它提供了一种简单的方式来管理应用程序中的事件,使得不同组件之间的通信更加方便和可维护。
具体的使用方式可以查看:https://blog.csdn.net/weixin_41897680/article/details/131430205
通过Mitt的方式我们就可以将图层和数据源达成触发条件就通信的形式。
至于写成组件的肯定是为了减少更多的代码操作,所以我们可以给他们这些组件分别添加指定属性监听以及一些操作监听,而如果想通过v-if进行控制图层或地图或其他用JS代码生成的样式,这个就可以通过在vue3的生命周期中的onUnmounted 周期里进行销毁来完成显示隐藏。
以上所说的关于地图框架进行的封装概念也可以用于其他类似的框架或者工具包。