vue3 地图(天地图,百度地图,腾讯地图,高德地图)封装组件调用 带地图搜索功能common_tencent_map_ak

废话不多说直接上组件代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
<template>
    <!-- 地图 -->
    <div class="container w">
        <div id="map" class="map radius-md" :style="{ width: width, height: height }"></div>
    </div>
</template>
<script>
export default defineComponent({
    props: {
        modelValue: {
            type: String,
            default: '上海市黄浦区上海中心大厦',
        },
        // 是否可拖拽
        draggable: {
            type: Boolean,
            default: true,
        },
        width: {
            type: String,
            default: '100%',
        },
        height: {
            type: String,
            default: '350px',
        },
        type: {
            type: String,
            default: 'baidu', // 地图类型 默认1.tianditu天地图/2.baidu百度地图/3.tencent腾讯地图/4.amap高德地图
        },
    },
    emits: ['point'],
    setup(props, context) {
     // 密钥 <br>        const common_amap_map_ak = 'xxxxxxxxxxx';
        const common_amap_map_safety_ak = 'xxxxxxxxxx';
        const common_baidu_map_ak = 'xxxxxxxxxx';
        const common_tencent_map_ak = 'xxxxxxxxx';
        const common_tianditu_map_ak = 'xxxxxxxxxxx';
        const map = ref(null);
        const lng = ref(121.47894);
        const lat = ref(31.223);
        watch(
            () => props.modelValue,
            (val) => {
                if (!val) return;
                map_event(val);
            }
        );
        onMounted(() => {
            load_map_script(); // 加载地图资源
        });
        const load_map_script = () => {
            // 此处在所需页面引入资源就是,不用再public/index.html中引入
            let script = document.createElement('script');
            script.type = 'text/javascript';
            script.className = 'loadmap'; // 给script一个类名
            if (props.type === '1') {
                // 天地图
                script.src = `https://api.tianditu.gov.cn/api?v=4.0&tk=${common_tianditu_map_ak || 'xxx'}`;
            } else if (props.type === '2') {
                // 百度地图
                script.src = `https://api.map.baidu.com/getscript?v=3.0&ak=${common_baidu_map_ak || 'xxx'}`;
            } else if (props.type === '3') {
                // 腾讯地图
                script.src = `https://map.qq.com/api/js?v=2.exp&key=${common_tencent_map_ak || 'xxx'}&callback=init`;
            } else if (props.type === '4') {
                // 高德地图
                script.src = `https://webapi.amap.com/maps?v=2.0&key=${common_amap_map_ak || 'xxx'}`;
            }
            // 使用script.onload,待资源加载完成,再初始化地图
            if (props.type === '3') {
                window.init = () => {
                    init();
                };
                load_tx_map();
            } else {
                script.onload = () => {
                    init();
                };
            }
            let loadmap = document.getElementsByClassName('loadmap');
            if (loadmap) {
                // 每次append script之前判断一下,避免重复添加script资源标签
                for (var i = 0; i < loadmap.length; i++) {
                    document.body.removeChild(loadmap[i]);
                }
            }
            if (props.type === '4') {
                window._AMapSecurityConfig = {
                    securityJsCode: common_amap_map_safety_ak || 'xxx',
                };
            }
            document.body.appendChild(script);
        };
 
        const load_tx_map = () => {
            // 此处在所需页面引入资源就是,不用再public/index.html中引入
            let script = document.createElement('script');
            script.type = 'text/javascript';
            script.className = 'loadmap2'; // 给script一个类名
            script.src = `https://map.qq.com/api/gljs?v=1.exp&key=${common_tencent_map_ak || 'xxx'}&libraries=service`;
            let loadmap2 = document.getElementsByClassName('loadmap2');
            if (loadmap2) {
                // 每次append script之前判断一下,避免重复添加script资源标签
                for (var i = 0; i < loadmap2.length; i++) {
                    document.body.removeChild(loadmap2[i]);
                }
            }
            document.body.appendChild(script);
        };
        // 初始化地图
        const init = () => {
            switch (props.type) {
                case '1':
                    const T = window.T;
                    // 坐标
                    map.value = new T.Map('map');
                    let point = new T.LngLat(lng.value, lat.value);
                    map.value.centerAndZoom(point, 10);
                    // 禁止鼠标滚动缩小放大
                    map.value.disableScrollWheelZoom();
 
                    // 添加控件
                    //创建缩放平移控件对象
                    let control = new T.Control.Zoom();
                    // control.setPosition(T_ANCHOR_TOP_RIGHT);
                    //添加缩放平移控件
                    map.value.addControl(control);
 
                    map.value.clearOverLays();
                    let marker = new T.Marker(point);
                    map.value.addOverLay(marker);
                    if (props.draggable) {
                        marker.enableDragging();
                        marker.addEventListener('dragend', function (e) {
                            map.value.panTo(new T.LngLat(e.lnglat.lng, e.lnglat.lat));
                            lat.value = e.lnglat.lat;
                            lng.value = e.lnglat.lng;
                            context.emit('point', lng, lat);
                        });
                    }
                    break;
                case '2':
                    const BMap = window.BMap;
                    map.value = new BMap.Map('map', {
                        enableMapClick: false,
                    });
                    let point2 = new BMap.Point(lng.value, lat.value);
                    map.value.centerAndZoom(point2, 10); // 初始化地图,设置中心点坐标和地图级别
                    // 添加控件
                    let navigationControl = new BMap.NavigationControl({
                        // 靠左上角位置
                        anchor: window.BMAP_ANCHOR_TOP_LEFT,
                        // LARGE类型
                        type: window.BMAP_NAVIGATION_CONTROL_LARGE,
                    });
                    map.value.addControl(navigationControl);
                    let marker2 = new BMap.Marker(point2);
                    map.value.addOverlay(marker2);
                    if (props.draggable) {
                        // 修正marker的初始化
                        marker2.enableDragging();
                        marker2.addEventListener('dragend', function (e) {
                            map.value.panTo(e.point);
                            lat.value = e.point.lat;
                            lng.value = e.point.lng;
                            context.emit('point', lng, lat);
                        });
 
                        // 设置标注提示信息
                        let cr = new BMap.CopyrightControl({ anchor: window.BMAP_ANCHOR_BOTTOM_RIGHT });
                        map.value.addControl(cr); //添加版权控件
                        let bs = map.value.getBounds(); //返回地图可视区域
                        cr.addCopyright({ id: 1, content: '<div class="map-dragging-tips"><span>' + '拖动红色图标直接定位' + '</span></div>', bounds: bs });
                    }
                    break;
                case '3':
                    const qq_maps = window.qq.maps;
                    let point3 = new qq_maps.LatLng(lat.value, lng.value);
                    map.value = new qq_maps.Map('map', {
                        center: point3,
                        zoom: 10,
                    });
                    let marker3 = new qq_maps.Marker({
                        map: map.value,
                        position: point3,
                        draggable: props.draggable,
                    });
                    qq_maps.event.addListener(marker3, 'dragend', function (e) {
                        lat.value = e.latLng.lat;
                        lng.value = e.latLng.lng;
                        map.value.panTo(e.latLng);
                        context.emit('point', lng, lat);
                    });
                    break;
                case '4':
                    const AMap = window.AMap;
                    map.value = new AMap.Map('map', {
                        zoomEnable: true,
                        resizeEnable: false,
                        scrollWheel: false,
                        zoom: 10, // 初始化地图级别
                        center: [lng.value, lat.value], // 初始化地图中心点位置
                    });
                    AMap.plugin(['AMap.ToolBar'], function () {
                        // 在图面添加工具条控件, 工具条控件只有缩放功能
                        map.value.addControl(new AMap.ToolBar());
                    });
                    // 创建标注
                    var marker_config = {
                        position: map.value.getCenter(),
                        // offset: new AMap.Pixel(-13, -30),
                        draggable: props.draggable,
                    };
                    let marker4 = new AMap.Marker(marker_config);
                    marker4.setMap(map);
                    // 标注可拖拽回调
                    if (props.draggable) {
                        marker4.on('dragend', (e) => {
                            map.value.panTo(e.lnglat);
                            lng.value = e.lnglat.lng;
                            lat.value = e.lnglat.lat;
                            context.emit('point', lng.value, lat.value);
                        });
                    }
                    map.value.add(marker4);
                    break;
            }
        };
        const map_event = (value) => {
            switch (props.type) {
                case '1':
                    let geo = new T.Geocoder();
                    geo.getPoint(value, function (result) {
                        let point = result.getLocationPoint();
                        if (result.getStatus() == 0) {
                            lng.value = point.lng;
                            lat.value = point.lat;
                            init();
                            map.value.panTo(new T.LngLat(lng.value, lat.value));
                            context.emit('point', lng.value, lat.value);
                        } else {
                            ElMessage.info(point?.getMsg() || '您选择地址没有解析到结果!');
                        }
                    });
                    break;
                case '2':
                    // 创建地址解析器实例
                    let geo2 = new window.BMap.Geocoder();
                    // 将地址解析结果显示在地图上,并调整地图视野
                    geo2.getPoint(
                        value,
                        function (point) {
                            if (point) {
                                lng.value = point.lng;
                                lat.value = point.lat;
                                context.emit('point', lng.value, lat.value);
                                init();
                            } else {
                                ElMessage.info(point?.getMsg() || '您选择地址没有解析到结果!');
                            }
                        },
                        '全国'
                    );
                    break;
                case '3':
                    let geo3 = new TMap.service.Geocoder();
                    geo3.getLocation({ address: value }).then((result) => {
                        let lnglat = result.result.location;
                        lng.value = lnglat.lng;
                        lat.value = lnglat.lat;
                        init();
                        context.emit('point', lng.value, lat.value);
                    });
                    break;
                case '4':
                    AMap.plugin('AMap.Geocoder', () => {
                        new AMap.Geocoder().getLocation(value, (status, result) => {
                            if (status === 'complete' && result.geocodes.length) {
                                var lnglat = result.geocodes[0].location;
                                lng.value = lnglat.lng;
                                lat.value = lnglat.lat;
                                init();
                                context.emit('point', lng.value, lat.value);
                            } else {
                                ElMessage.info('您选择地址没有解析到结果!');
                            }
                        });
                    });
                    break;
            }
        };
    },
});
</script>
<style lang="scss" scoped></style>

 

组件调用及回调:

1
<maps v-model="map_address" :type="common_map_type" @point="map_point"></maps>
 
参数:
1
2
3
4
// 地址
const map_address = ref('');
// 地图类型
const map_type = ref('tianditu');
 
组件回调:
1
2
3
4
5
//地图用于回调用于获取坐标
const map_point = (lng: number, lat: number) => {
    form.lng = lng;
    form.lat = lat;
};

 

 地图效果展示:

 

 

 

 

posted @   吃不棒的胖胖糖  阅读(1167)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示