介绍
最初的灵感来源于,能否实现动态创建一个 vue 组件,并添加到页面上显示出来。
后来开发地图场景,需要使用 mapbox 的 marker 做地图扎点,而 mapbox 的扎点实际使用的是 dom ,如此一来便萌生了能否使用 vue 来做扎点的想法。
在经历几个版本的迭代后,迎来了 mapbox-vue-marker 的诞生!
使用Mapbox-Vue-Marker,你可以通过 vue 组件的方式,向地图添加扎点marker,实现完全由数据驱动的UI逻辑,工欲善其事必先利其器,方能事半功倍!
安装
npm install mapbox-vue-marker --save
目前仅支持通过 npm 安装
注意!本插件需要同时使用vue和mapboxgl
国内建议使用 cnpm 进行安装
cnpm install mapbox-vue-marker --save
注册组件
通过 npm 安装之后,需要在 main.js 注册该插件
import store from './store'
import mapboxgl from 'mapbox-gl'
import 'mapbox-gl/dist/mapbox-gl.css'
import mapboxvuemarker from 'mapbox-vue-marker'
let plugOptions = {
mapboxgl,router,store,
// 可通过rename修改默认的方法名
// rename:{
// '$addMarker':'addMK',
// '$removeMarker':'delMk',
// '$makeMarker':'makeMK'
// }
}
Vue.use(mapboxvuemarker,plugOptions)
Vue.config.productionTip = false
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
提示
router和store是可选参数
通过 Vue 提供的use方法注册该组件,传入插件对象和配置对象
配置对象的参数如下
options = {
mapboxgl, //mapboxgl对象(必须)
router, //vue的router(可选)
store, //vuex对象(可选)
}
到此插件的配置就完成了!
重命名插件方法
我们向 Vue 的原型链上添加了三个基础方法,为了排除命名冲突的问题,我们提供了修改命名的方法
插件在 main.js 中注册的时候,可传递一个 rename 字段,该字段的值必须是一个对象。
let plugOptions = {
mapboxgl,router,store,
rename:{
'$addMarker':'addMK',
'$removeMarker':'delMk',
'$makeMarker':'makeMK'
}
}
Vue.use(mapboxvuemarker,plugOptions)
上述代码可以看出,键名为要修改的方法,键值为修改的结果
$makeMarker 创建marker
在配置好环境以后,我们正式开始创建marker,以下是一个创建marker的小例子 首先我们创建一个基本的 vue 组件
<template>
<div class="vuemarker">V</div>
</template>
<script>
export default {
name: "vuemarker",
}
</script>
现在我们把这个 vue 组件导出
mapboxgl.accessToken = 'token';
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v11',
center: [-74.50, 40],
zoom: 9
});
let marker = this.$makeMarker({
lnglat:map.getCenter(),
component:vuemarker,
});
上述代码创建了一个最基本的mapbox地图,然后通过插件的全局方法 $makeMarker 方法创建了一个marker对象,并赋值给 marker 变量
提示
$makeMarker方法接受一个配置对象,返回标准的mapbox的marker对象
$makeMarker的详细配置参数有:
let options = {
lnglat,//marker在地图上的经纬度(必须)
component,//组成marker的 vue 组件
anchor,//marker的中心点,详情见mapbox官网介绍,默认为bottom
props,//vue组件接收的参数对象,默认为空对象
draggable,//marker是否可拖动,默认为false
zIndex,//扎点的层级,默认为空
}
注意
$makeMarker的作用仅仅是创建marker
$addMarker 添加marker到地图
此时还需要调用$addMarker方法来添加marker到地图
this.$addMarker(this.marker,map)
$addMarker的两个参数都为必填项,第一个参数可以是marker对象,也可以是包含marker的数组或对象,第二个参数为map对象
方法内部会遍历参数对象的所有深度,移除参数对象包含的所有marker
注意
只有那些通过$makeMarker方法制造的marker才能被该方法添加到地图
$removeMarker 移除marker
$removeMarker方法可以移除在地图上的marker
this.$removeMarker(this.marker)
该方法需要一个参数,即要移除的marker,和添加的方法相同,这个参数也可以是一个包含marker的数组或对象
注意
只有那些通过$makeMarker方法制造的marker才能被该方法从地图移除
$getMarkerBox 数据存储
一定要注意
🙃如果没有开启markerBox,千万不要将marker放入vue组件的data中
🙃这会导致vue向marker对象设置无效的getter和setter
🙃您可能会需要手动实现marker的存储,并在beforeDestroy钩子中销毁
在实际项目中,更多可能的是会面临多种类多数量的marker
在此提供一种保存数据的想法
let markerbox = this.getMarkerBox()
如果需要插件来代理存储marker,您需要在调用$makeMarker方法时传入参数usebox(boolean)和markerType(string)
let markerbox={
type1:[marker],
other:[]
}
传入的类型会被存储为markerbox对象下的数组
提示
开启usebox功能后,如果没有传入markerType,那么这个marker将被归类到other分类下
行为分析
标准对象
$addMarker 和 $removeMarker 仅对与通过 $makeMarker 方法构建的marker生效
vue-marker组件默认行为
$makeMarker 构造完毕后,会立刻执行 vue 组件的 mounted 方法,并且将一直处于挂载状态
考虑到业务中的逻辑,我们提供了 $addMarker 和 $removeMarker 的回调方法,您可以在 vue 组件的 methods 中提供 onAdd 和 onRemove 方法,它们将作为回调方法自动调用
marker层级
我们默认接管了 marker 的层级关系,它在每次拖动地图时,都会进行计算并更新层级参数
您可以在构建 marker 时传入 zIndex 来设置为固定层级
参数传递
我们默认向 vue 组件提供了两个 props ,分别是 marker 对象和 parent 对象,parent 指向调用构造 marker 方法的 vue 实例
marker对象默认行为
mapbox 的 marker 也具有默认行为,当您调用 $addMarker 的时候,它将首先调用一次 remove方法,您需要注意调用回调时,可能产生不可预知的错误