一、概述
最近项目中用到了Vuelayers这一组件库(参考文档),这里简单记录下开发中遇到的问题;
1. 功能描述
将下图中红色方框内的按钮往下移指定像素位置
2. 功能实现
在做地图展示时会用到一个<vl-map></vl-map>
标签,示例代码如下:
<vl-map v-if="mapVisible"
class="map" ref="map"
:load-tiles-while-animating="true"
:load-tiles-while-interacting="true"
@click="clickCoordinate = $event.coordinate"
@postcompose="onMapPostCompose"
data-projection="EPSG:4326"
@mounted="onMapMounted"></vl-map>
要实现前面的按钮的样式调整只需要为标签传入defaultControls
属性即可,示例代码如下:
<vl-map v-if="mapVisible"
class="map" ref="map"
:load-tiles-while-animating="true"
:load-tiles-while-interacting="true"
:defaultControls="mapControl"
@click="clickCoordinate = $event.coordinate"
@postcompose="onMapPostCompose"
data-projection="EPSG:4326"
@mounted="onMapMounted"></vl-map>
mapControl: {
zoom: true,
zoomOptions: {
zoomInTipLabel: '放大',
zoomOutTipLabel: '缩小',
className: 'map-layer-zoom-button'
}
},
再为map-layer-zoom-button
添加对应样式即可。
二、代码分析
1. 相关的源码
- 在
VueLayers
中,调用者只需要在<vl-map>
标签中绑定的@mounted
事件中设置即可。this.$refs.map.$map.getControls().extend([ //添加全屏按钮 new FullScreen({ className: 'map-layer-full-screen', tipLabel: '全屏' }), //添加页面缩放条 new ZoomSlider({ className: 'map-layer-zoom-slider' }), ])
- 在上面的代码中可以看出,在添加地图控制组件时可以在创建对象时传入对应的参数控制其属性,源码如下:
var FullScreen = /*@__PURE__*/(function (Control) { // ······· // //这里可以通过创建对象时传入一个对象设置其样式名称 this.cssClassName_ = options.className !== undefined ? options.className : 'ol-full-screen'; // ······· // }
2. 分析
- 由上面的代码猜测在缩放按钮中也同样存在一个修改样式的入口,在
FullScreen.js
同级目录中找到Zoom.js
,根据内容基本上可以确定这个js文件就是用来控制前面那两个按钮的。 - 此时使用webstorm戳一下
Zoom
变量名,发现在同级目录的utils.js
中引入了这个文件,其代码如下:export function defaults(opt_options) { var options = opt_options ? opt_options : {}; var controls = new Collection(); var zoomControl = options.zoom !== undefined ? options.zoom : true; if (zoomControl) { controls.push(new Zoom(options.zoomOptions)); } var rotateControl = options.rotate !== undefined ? options.rotate : true; if (rotateControl) { controls.push(new Rotate(options.rotateOptions)); } var attributionControl = options.attribution !== undefined ?options.attribution : true; if (attributionControl) { controls.push(new Attribution(options.attributionOptions)); } return controls; }
- 使用全局搜索这个js文件可能的导入路径,例如
from 'ol/control
,最终确定在map.vue
中使用了这个js文件,代码为import { defaults as createDefaultControls } from 'ol/control'
- 在
map.vue
源码中搜索createDefaultControls
,发现在created
钩子中有一段代码如下,由此确定只需要defaultControls
属性在else if
中为true,它最终就会传递到Zoom.js
中,而defaultControls
定义在prors
中,所以只需要在<vl-map>
标签中传入即可。代码分析到这里基本上就能实现功能了。if (this.defaultControls instanceof Collection) { this._controlsCollection = this.defaultControls } else if (this.defaultControls !== false) { this._controlsCollection = createDefaultControls( isPlainObject(this.defaultControls) ? this.defaultControls : undefined, ) }
我的JS实在是菜,上面代码中类似于判断中的isPlainObject()
这些方法,戳进去之后balabala一大堆看不懂的就直接略过了。