Skip to content

Commit f723096

Browse files
committed
feat(component): add map component; !#zh: 添加地图组件
1 parent b982753 commit f723096

File tree

6 files changed

+272
-3
lines changed

6 files changed

+272
-3
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# lbp-qq-map
2+
> luban-h5-plugin-qq-map
3+
4+
为鲁班H5提供腾讯地图支持(https://lbs.qq.com/)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
function isScriptLoaded (src) {
2+
return !!document.querySelector('script[src="' + src + '"]')
3+
}
4+
export default {
5+
map: null,
6+
load: function (key) {
7+
return new Promise(function (resolve, reject) {
8+
const src = 'http://map.qq.com/api/js?v=2.exp&libraries=place&callback=init&key=' + key
9+
if (isScriptLoaded(src)) {
10+
resolve(window.qq)
11+
return
12+
}
13+
window.init = function () {
14+
resolve(window.qq)// 注意这里
15+
}
16+
var script = document.createElement('script')
17+
script.type = 'text/javascript'
18+
script.src = src
19+
script.onerror = reject
20+
document.head.appendChild(script)
21+
})
22+
},
23+
getPosition ({ lat, lng }) {
24+
return new window.qq.maps.LatLng(lat, lng) // 地图的中心地理坐标
25+
}
26+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
<template>
2+
<div>
3+
<div id="qq-map-container" ref="mapElement" style="height: 100%;width: 100%"></div>
4+
</div>
5+
</template>
6+
<script>
7+
import PropTypes from '@luban-h5/plugin-common-props'
8+
import Map from './Map'
9+
import MapMixin from './mixin'
10+
11+
export default {
12+
// extra.defaultStyle:组件的额外自定义配置,以拖拽组件到画布上为例
13+
// 按钮默认的样式可能是: { width: 100px, height: 40px }
14+
// 但地图可能是希望更大一些的默认样式,比如:{ width: 320px, height: 180px }
15+
// 就可以通过 extra.defaultStyle 来实现自定义样式需求
16+
extra: {
17+
defaultStyle: {
18+
width: 320,
19+
height: 180
20+
}
21+
},
22+
name: 'lbp-qq-map',
23+
mixins: [MapMixin], // loadMap、setMarker
24+
props: {
25+
labelContent: PropTypes.string({ label: '地址名称', defaultValue: '' }), // 标签内容
26+
zoomLevel: PropTypes.number({ label: '缩放层级', defaultValue: 12, visible: false }),
27+
// https://lbs.qq.com/dev/console/key/manage
28+
qqMapKey: PropTypes.string({
29+
label: '腾讯地图Key',
30+
defaultValue: 'GENBZ-G5S3J-7OLFW-FLBX4-WVEMK-SOBL4',
31+
component: 'a-textarea',
32+
extra: (h) => {
33+
return <div>
34+
<div>1. 请填入自己的腾讯地图开发密钥,<a href="https://lbs.qq.com/dev/console/key/manage" target="_blank">前往申请&gt;&gt;</a></div>
35+
<div>2. 鲁班的 Demo Key 随时可能失效;失效提示: 鉴权失败,请传入正确的key</div>
36+
</div>
37+
}
38+
}),
39+
poi: {
40+
type: Object,
41+
default: () => ({
42+
'latLng': {
43+
'lat': 39.90469,
44+
'lng': 116.40717
45+
},
46+
'name': '北京市',
47+
'type': 4
48+
}),
49+
editor: {
50+
custom: true
51+
}
52+
}
53+
},
54+
watch: {
55+
poi: {
56+
handler (poi) {
57+
if (!this.checkMapAvailable()) return
58+
this.setMarker(poi)
59+
},
60+
deep: true
61+
},
62+
labelContent (labelContent) {
63+
if (!this.checkMapAvailable()) return
64+
this.setLabel(labelContent)
65+
},
66+
zoomLevel (zoomLevel) {
67+
if (!this.checkMapAvailable()) return
68+
this.setZoomLevel(zoomLevel)
69+
}
70+
},
71+
methods: {
72+
checkMapAvailable () {
73+
return window.qq && window.qq.maps
74+
},
75+
onSearch (value) {
76+
console.log(value)
77+
},
78+
setLabel (labelContent) {
79+
const center = Map.getPosition(this.poi.latLng) // 地图的中心地理坐标
80+
this.label = this.label || new window.qq.maps.Label({
81+
position: center,
82+
map: this.map,
83+
content: ''
84+
})
85+
if (labelContent.trim()) {
86+
// https://lbs.qq.com/webDemoCenter/javascriptV2/marker/label
87+
this.label.setVisible(true)
88+
this.label.setContent(labelContent || '')
89+
this.label.setPosition(center)
90+
} else {
91+
this.label.setVisible(false)
92+
}
93+
},
94+
setZoomLevel (zoomLevel) {
95+
this.map.zoomTo(zoomLevel)
96+
},
97+
init () {
98+
const { poi, qqMapKey } = this
99+
this.loadMap(qqMapKey).then(qq => {
100+
this.initMap(poi)
101+
this.setLabel(this.labelContent)
102+
this.setMarker(poi)
103+
})
104+
},
105+
initMap (poi) {
106+
const el = this.$refs.mapElement
107+
const center = Map.getPosition(poi.latLng) // 地图的中心地理坐标
108+
this.map = new window.qq.maps.Map(el, {
109+
center,
110+
zoom: this.zoomLevel, // 设置地图的缩放级别
111+
disableDefaultUI: true, // 禁止所有控件
112+
draggable: false, // 设置是否可以拖拽
113+
scrollwheel: false, // 设置是否可以滚动
114+
disableDoubleClickZoom: true // 设置是否可以双击放大
115+
// 设置地图样式详情参见MapType
116+
})
117+
}
118+
},
119+
mounted () {
120+
this.init()
121+
}
122+
}
123+
</script>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import Map from './Map'
2+
3+
function getPosition ({ lat, lng }) {
4+
return new window.qq.maps.LatLng(lat, lng) // 地图的中心地理坐标
5+
}
6+
7+
export default {
8+
methods: {
9+
loadMap (key) {
10+
return Map.load(key)
11+
},
12+
setMarker (poi) {
13+
const map = this.map
14+
const center = getPosition(poi.latLng) // 地图的中心地理坐标
15+
if (this.marker) {
16+
this.marker.setMap(null)
17+
this.marker = new window.qq.maps.Marker({ map, position: poi.latLng })
18+
map.panTo(center)
19+
} else {
20+
this.marker = new window.qq.maps.Marker({ map, position: center })
21+
}
22+
}
23+
}
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
import Map from './lbp-qq-map/src/Map'
2+
import MapMixin from './lbp-qq-map/src/mixin'
3+
4+
export default {
5+
name: 'lbp-qq-map__editor',
6+
mixins: [MapMixin], // loadMap、setMarker
7+
props: {
8+
// 地图的props 集合
9+
elementProps: {
10+
type: Object,
11+
default: () => ({
12+
labelContent: '',
13+
zoomLevel: 12
14+
})
15+
}
16+
},
17+
methods: {
18+
/**
19+
* 更新组件的 poi prop
20+
* @param {Object} poi 参考 lbp-qq-map 的 poi prop,用来表示坐标点信息
21+
*/
22+
setPoi (poi) {
23+
this.elementProps.poi = poi
24+
},
25+
// https://lbs.qq.com/webDemoCenter/javascriptV2/libraries/placeLibrary
26+
initSearch () {
27+
const self = this
28+
let keyword = ''
29+
30+
// 调用Poi检索类。用于进行本地检索、周边检索等服务。
31+
const searchService = new window.qq.maps.SearchService({
32+
complete: results => {
33+
if (results.type === 'CITY_LIST') {
34+
searchService.setLocation(results.detail.cities[0].cityName)
35+
searchService.search(keyword)
36+
return
37+
}
38+
const poi = results.detail.pois[0]
39+
self.setMarker(poi)
40+
self.setPoi(poi)
41+
}
42+
})
43+
// 添加监听事件
44+
const qqMapSearchElement = document.getElementById('editor__qq-map-search')
45+
const ap = new window.qq.maps.place.Autocomplete(qqMapSearchElement)
46+
47+
window.qq.maps.event.addListener(ap, 'confirm', function (res) {
48+
keyword = res.value
49+
searchService.search(keyword)
50+
})
51+
},
52+
/**
53+
* 监听地图 缩小/放大
54+
*/
55+
listenZoom () {
56+
window.qq.maps.event.addListener(this.map, 'zoom_changed', () => {
57+
this.elementProps.zoomLevel = this.map.getZoom()
58+
})
59+
},
60+
initMap (poi) {
61+
const center = Map.getPosition(poi.latLng) // 地图的中心地理坐标
62+
const el = document.getElementById('editor__qq-map-container')
63+
this.map = new window.qq.maps.Map(el, {
64+
center,
65+
zoom: 8, // 设置地图的缩放级别
66+
disableDefaultUI: true // 禁止所有控件
67+
// 设置地图样式详情参见MapType
68+
})
69+
},
70+
init () {
71+
const { poi, qqMapKey } = this.elementProps
72+
this.loadMap(qqMapKey).then(qq => {
73+
this.initMap(poi)
74+
this.setMarker(poi)
75+
this.initSearch()
76+
this.listenZoom()
77+
})
78+
}
79+
},
80+
mounted () {
81+
this.init()
82+
},
83+
render () {
84+
return (
85+
<div style="margin: 12px;">
86+
<input ref="search" id="editor__qq-map-search" placeholder="请输入地名" style="width: 100%;margin-bottom: 20px;" />
87+
<div id="editor__qq-map-container" style="padding-bottom: 60%;width: 100%"></div>
88+
</div>
89+
)
90+
}
91+
}

front-end/h5/src/mixins/load-plugins.js

+4-3
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import LbpSlide from '../components/plugins/lbp-slide'
1313
import LbpBgMusic from '../components/plugins/lbp-bg-music'
1414
import LbpNoticeBar from '../components/plugins/lbp-notice-bar'
1515
import LbpRate from '../components/plugins/lbp-rate'
16+
import LbpQQMap from '../components/plugins/lbp-qq-map/src'
1617
// import LbpTabs from '../components/plugins/lbp-tabs'
1718

1819
export const pluginsList = [
@@ -101,10 +102,10 @@ export const pluginsList = [
101102
},
102103
title: '地图',
103104
icon: 'map-o',
104-
component: LbpFormRadioGroup,
105+
component: LbpQQMap,
105106
visible: true,
106-
name: LbpFormRadioGroup.name,
107-
disabled: true
107+
name: LbpQQMap.name
108+
// disabled: true
108109
},
109110
{
110111
i18nTitle: {

0 commit comments

Comments
 (0)