Vue<地图搜索定位功能>
2020-08-01 本文已影响0人
誰在花里胡哨
效果图:


官方地址:https://lbs.qq.com/
如果你想创建一个地图,那么你就要去申请一个key,然后放在 index.html里面引入
<script src="https://map.qq.com/api/gljs?v=1.exp&key=你申请的key"></script>
然后在对应的组件内就能创建地图了,⚠️要放到 mounted 周期内执行
<div id="container"></div>
//初始化地图
initMap() {
var center = new TMap.LatLng(39.984104, 116.307503);
//初始化地图
this.map = new TMap.Map("container", {
rotation: 20, //设置地图旋转角度
pitch: 0, //设置俯仰角度(0~45)
zoom: 16, //设置地图缩放级别
center: center //设置地图中心点坐标
});
},
当然上面只是简单的地图使用,如果你想使用腾讯地图更多的功能或api,那你就需要调用第三方接口了。
地点搜索:

地点搜索:点击查看文档地址
首先客户端调用,需要解决跨域问题,这边我是在 vue.config.js 进行配置的,在proxy里面可以配置多个跨域地址。
⚠️注意:要加上 pathRewrite: { '^/place': '' //重写接口 }(很扯的一个坑)
proxy: {
// '/api': {
// target: 'https://xxxxx.com/api', //目标接口域名
// changeOrigin: true, //是否跨域
// pathRewrite: {
// '^/api': '' //重写接口
// }
// },
"/place": {
target: "https://apis.map.qq.com",
changeOrigin: true,
ws: true,
pathRewrite: {
'^/place': '' //重写接口
}
},
},
配置完之后记得重新 npm run dev下,不然保存是无效的。
import axios from "axios";
axios({
url: `/place/ws/place/v1/suggestion?keyword=搜索内容&key=你申请的key`,
method: "GET"
})
.then(res => {
if (res.data) {
//搜索结果
this.addressList = res.data.data;
}
})
.catch(err => {
console.log(err);
});
定位:

有提供api接口,但是不怎么好用,点击参考api接口地址;
所以建议大家参考腾讯给的另一种方案,点击查看前端定位组件;
index.html引入,其他部分建议参考文档来
<script type="text/javascript" src="https://3gimg.qq.com/lightmap/components/geolocation/geolocation.min.js"></script>

具体其他功能,大家可参考文档,大部分的地图使用也基本这样。
⚠️注意:下面的完整代码没有涉及到定位功能,不过参考上面提到的 前端地位组件,实现起来也是很简单的。
完整代码:
<template>
<div class="app-content">
<div class="Map">
<div class="search_Map">
<input type="text" v-model="value" @input="search(value)" />
<div class="content">
<p v-for="(i,index) in addressList" :key="index" @click="select(i)">
{{i.title}}
<span class="address">{{i.address}}</span>
</p>
</div>
</div>
<div id="container"></div>
</div>
</div>
</template>
<script>
import axios from "axios";
export default {
data() {
return {
value: "", //搜索内容
addressList: [], //搜索结果
selectValue: {}, //选择的某个结果
timeout: null, //搜索定时器
map: null,
marker: null
};
},
mounted() {
this.initMap();
},
methods: {
//初始化地图
initMap() {
var center = new TMap.LatLng(39.984104, 116.307503);
//初始化地图
this.map = new TMap.Map("container", {
rotation: 20, //设置地图旋转角度
pitch: 0, //设置俯仰角度(0~45)
zoom: 16, //设置地图缩放级别
center: center //设置地图中心点坐标
});
},
//地址搜索
search(value) {
this.addressList = [];
clearTimeout(this.timeout);
if (value) {
this.timeout = setTimeout(() => {
axios({
url: `/place/ws/place/v1/suggestion?keyword=${value}&key=你申请的key`,
method: "GET"
})
.then(res => {
if (res.data) {
this.addressList = res.data.data;
}
})
.catch(err => {
console.log(err);
});
}, 500);
}
},
//选择对应搜索地址
select(row) {
this.selectValue = row.location;
console.log(this.selectValue);
this.addressList = [];
let self = this;
//更新地图中心位置
self.map.setCenter(
new TMap.LatLng(this.selectValue.lat, this.selectValue.lng)
);
//判断是否存在标记点,有的话清空
if (self.marker) {
self.marker.setMap(null);
self.marker = null;
}
//初始化marker
self.marker = new TMap.MultiMarker({
id: "marker-layer", //图层id
map: self.map,
styles: {
//点标注的相关样式
marker: new TMap.MarkerStyle({
width: 25,
height: 35,
anchor: { x: 16, y: 32 },
src:
"https://mapapi.qq.com/web/lbs/javascriptGL/demo/img/markerDefault.png"
})
},
geometries: [
{
//点标注数据数组
id: "demo",
styleId: "marker",
position: new TMap.LatLng(
self.selectValue.lat,
self.selectValue.lng
),
properties: {
title: "marker"
}
}
]
});
}
}
};
</script>
<style lang="scss" scoped>
.Map {
position: relative;
.search_Map {
position: absolute;
left: 20px;
top: 20px;
z-index: 99009;
input {
border: 1px solid #f1f1f1;
display: inline-block;
width: 400px;
height: 40px;
padding: 10px;
color: #5a5a5a;
background: rgba(255, 255, 255, 0.904);
}
.content {
width: 400px;
background: rgba(252, 250, 250, 0.918);
border: 1px solid #f1f1f1;
border-top: none;
font-size: 13px;
color: #5a5a5a;
max-height: 350px;
overflow-y: auto;
p {
display: inline-block;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
width: 380px;
border-bottom: 1px solid #f1f1f1;
padding: 15px 10px;
margin: 0;
cursor: pointer;
&:hover {
background: #eff6fd;
}
.address {
font-size: 12px;
color: #b9b9b9;
margin-left: 20px;
}
}
}
}
}
#container {
width: 800px;
height: 400px;
}
</style>