先拓企业站
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

287 lines
7.4 KiB

<template>
<div>
<div v-if="!hasBmView" ref="view" style="width: 100%; height: 100%">
</div>
<slot></slot>
</div>
</template>
<script>
import bindEvents from '../base/bindEvent.js'
import {checkType} from '../base/util.js'
export default {
name: 'bm-map',
props: {
ak: {
type: String
},
center: {
type: [Object, String]
},
zoom: {
type: Number
},
minZoom: {
type: Number
},
maxZoom: {
type: Number
},
highResolution: {
type: Boolean,
default: true
},
mapClick: {
type: Boolean,
default: true
},
mapType: {
type: String
},
dragging: {
type: Boolean,
default: true
},
scrollWheelZoom: {
type: Boolean,
default: false
},
doubleClickZoom: {
type: Boolean,
default: true
},
keyboard: {
type: Boolean,
default: true
},
inertialDragging: {
type: Boolean,
default: true
},
continuousZoom: {
type: Boolean,
default: true
},
pinchToZoom: {
type: Boolean,
default: true
},
autoResize: {
type: Boolean,
default: true
},
theme: {
type: Array
},
mapStyle: {
type: Object
}
},
watch: {
center (val, oldVal) {
const {map, zoom} = this
if (checkType(val) === 'String' && val !== oldVal) {
map.centerAndZoom(val, zoom)
}
},
'center.lng' (val, oldVal) {
const {BMap, map, zoom, center} = this
if (val !== oldVal && val >= -180 && val <= 180) {
map.centerAndZoom(new BMap.Point(val, center.lat), zoom)
}
},
'center.lat' (val, oldVal) {
const {BMap, map, zoom, center} = this
if (val !== oldVal && val >= -74 && val <= 74) {
map.centerAndZoom(new BMap.Point(center.lng, val), zoom)
}
},
zoom (val, oldVal) {
const {map} = this
if (val !== oldVal && val >= 3 && val <= 19) {
map.setZoom(val)
}
},
minZoom (val) {
const {map} = this
map.setMinZoom(val)
},
maxZoom (val) {
const {map} = this
map.setMaxZoom(val)
},
highResolution () {
this.reset()
},
mapClick () {
this.reset()
},
mapType (val) {
const {map} = this
map.setMapType(global[val])
},
dragging (val) {
const {map} = this
val ? map.enableDragging() : map.disableDragging()
},
scrollWheelZoom (val) {
const {map} = this
val ? map.enableScrollWheelZoom() : map.disableScrollWheelZoom()
},
doubleClickZoom (val) {
const {map} = this
val ? map.enableDoubleClickZoom() : map.disableDoubleClickZoom()
},
keyboard (val) {
const {map} = this
val ? map.enableKeyboard() : map.disableKeyboard()
},
inertialDragging (val) {
const {map} = this
val ? map.enableInertialDragging() : map.disableInertialDragging()
},
continuousZoom (val) {
const {map} = this
val ? map.enableContinuousZoom() : map.disableContinuousZoom()
},
pinchToZoom (val) {
const {map} = this
val ? map.enablePinchToZoom() : map.disablePinchToZoom()
},
autoResize (val) {
const {map} = this
val ? map.enableAutoResize() : map.disableAutoResize()
},
theme (val) {
const {map} = this
map.setMapStyle({styleJson: val})
},
'mapStyle.features': {
handler (val, oldVal) {
const {map, mapStyle} = this
const {style, styleJson} = mapStyle
map.setMapStyle({
styleJson,
features: val,
style
})
},
deep: true
},
'mapStyle.style' (val, oldVal) {
const {map, mapStyle} = this
const {features, styleJson} = mapStyle
map.setMapStyle({
styleJson,
features,
style: val
})
},
'mapStyle.styleJson': {
handler (val, oldVal) {
const {map, mapStyle} = this
const {features, style} = mapStyle
map.setMapStyle({
styleJson: val,
features,
style
})
},
deep: true
},
mapStyle (val) {
const {map, theme} = this
!theme && map.setMapStyle(val)
}
},
methods: {
setMapOptions () {
const {map, minZoom, maxZoom, mapType, dragging, scrollWheelZoom, doubleClickZoom, keyboard, inertialDragging, continuousZoom, pinchToZoom, autoResize} = this
minZoom && map.setMinZoom(minZoom)
maxZoom && map.setMaxZoom(maxZoom)
mapType && map.setMapType(global[mapType])
dragging ? map.enableDragging() : map.disableDragging()
scrollWheelZoom ? map.enableScrollWheelZoom() : map.disableScrollWheelZoom()
doubleClickZoom ? map.enableDoubleClickZoom() : map.disableDoubleClickZoom()
keyboard ? map.enableKeyboard() : map.disableKeyboard()
inertialDragging ? map.enableInertialDragging() : map.disableInertialDragging()
continuousZoom ? map.enableContinuousZoom() : map.disableContinuousZoom()
pinchToZoom ? map.enablePinchToZoom() : map.disablePinchToZoom()
autoResize ? map.enableAutoResize() : map.disableAutoResize()
},
init (BMap) {
if (this.map) {
return
}
let $el = this.$refs.view
for (let $node of this.$slots.default || []) {
if ($node.componentOptions && $node.componentOptions.tag === 'bm-view') {
this.hasBmView = true
$el = $node.elm
}
}
const map = new BMap.Map($el, {enableHighResolution: this.highResolution, enableMapClick: this.mapClick})
this.map = map
const {setMapOptions, zoom, getCenterPoint, theme, mapStyle} = this
theme ? map.setMapStyle({styleJson: theme}) : map.setMapStyle(mapStyle)
setMapOptions()
bindEvents.call(this, map)
// 此处强行初始化一次地图 回避一个由于错误的 center 字符串导致初始化失败抛出的错误
map.reset()
map.centerAndZoom(getCenterPoint(), zoom)
this.$emit('ready', {BMap, map})
// Debug
// global.map = map
// global.mapComponent = this
},
getCenterPoint () {
const {center, BMap} = this
switch (checkType(center)) {
case 'String': return center
case 'Object': return new BMap.Point(center.lng, center.lat)
default: return new BMap.Point()
}
},
initMap (BMap) {
this.BMap = BMap
this.init(BMap)
},
getMapScript () {
if (!global.BMap) {
const ak = this.ak || this._BMap().ak
global.BMap = {}
global.BMap._preloader = new Promise((resolve, reject) => {
global._initBaiduMap = function () {
resolve(global.BMap)
global.document.body.removeChild($script)
global.BMap._preloader = null
global._initBaiduMap = null
}
const $script = document.createElement('script')
global.document.body.appendChild($script)
$script.src = `https://api.map.baidu.com/api?v=2.0&ak=${ak}&callback=_initBaiduMap`
})
return global.BMap._preloader
} else if (!global.BMap._preloader) {
return Promise.resolve(global.BMap)
} else {
return global.BMap._preloader
}
},
reset () {
const {getMapScript, initMap} = this
getMapScript()
.then(initMap)
}
},
mounted () {
this.reset()
},
data () {
return {
hasBmView: false
}
}
}
</script>