需求:
1、点击编辑图标能打开对弹窗选值地址。
2、店铺经纬度为空时,默认定位到浏览器当前定位。有值时,定位到提供的经纬度。
3、2种方法选择地址:输入关键词可以搜索地址,移动定位图标也可以选择地址。
4、地图的key由客户提供,后端返回,不能写死。
高德地图
一、使用npm方式安装高德地图
npm i @amap/amap-jsapi-loader --save
二、页面中引入并使用
<template>
<div @click="showMapBtn1" class="addressBox">
<span :class="{ 'mr-8px': detailData.storeAddress }">{{ detailData.storeAddress }}</span>
<img class="imgs" src="/src/assets/images/editAddress.png" style="width: 16px;height: 16px;" />
</div>
<a-modal v-model:visible="showMap1" width="50%" title="地图选点" @ok="setMap1" style="top: 12vh;">
<div class="gdMapWrapper">
<div id="gdMapContainer"
style=" height: 222px;width: 100%;border: none;border-radius: 8px;margin-bottom: 24px; background-color: #f9fafb; display: flex;justify-content: center; align-items: center;">
<a-spin v-if="isLoadingMap" :indicator="indicator" />
</div>
<div class="searchContainer">
<a-input class="searchMapInput" v-model:value="word" placeholder="请输入详细地址" @change="searchMap"></a-input>
<div class="poiListContainer" v-if="poiList.length > 0">
<div class="poiListContainerItem" v-for="(item, index) in poiList" :key="item.id"
@click="selectPoi(item, index)">
<div class="left">
<div class="row1">{{ item.name }}</div>
<div class="row2">{{ item.address }}</div>
</div>
<div class="right">
<div :class="{ 'active': activeId == item.id }">
<img v-if="activeId == item.id" :src="img2" />
</div>
</div>
</div>
</div>
</div>
</div>
</a-modal>
</template>
<script>
import AMapLoader from "@amap/amap-jsapi-loader";
import { Button, message, Modal, Spin} from 'ant-design-vue';
import { getAutonaviKey } from '/@/api/merchant';
export default defineComponent({
name: 'MerchantDetail',
components: {
Button,
AModal: Modal,
ASpin: Spin,
},
setup() {
// 高德地图相关-------------------------
let keyInfo = { secret: '', key: '' } //高德key
const word = ref() //搜索关键词
const cityCode = ref() //用于地图搜索周边区域
let lngLatArr = [] //当前店铺的经纬度
let poiList = ref([]) //搜索地址结果列表
const isLoadingMap = ref(false)
const indicator = h(LoadingOutlined, { //loading效果
style: {
fontSize: '36px',
},
spin: true,
});
// 初始化地图
async function initMap(data) {
//获取地图的key
keyInfo = await getAutonaviKey();
window._AMapSecurityConfig = {
securityJsCode: keyInfo.secret,
}
// 先判断店铺是否有已存入地址
if (Number(data.longitude) !== 0 && Number(data.latitude) !== 0) {
lngLatArr = [+data.longitude, +data.latitude]
} else {
lngLatArr = []
}
AMapLoader.load({
key: keyInfo.key, // 申请好的Web端开发者Key,首次调用 load 时必填
version: "2.0", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
// plugins:[''], // 需要使用的的插件列表,如比例尺'AMap.Scale'等
}).then(async (AMap) => {
// 没有地址,默认浏览器当前定位
function getCurrentPosition() {
return new Promise((resolve, reject) => {
var options = {
'showButton': false,//是否显示定位按钮
'position': 'LB',//定位按钮的位置
/* LT LB RT RB */
'offset': [10, 20],//定位按钮距离对应角落的距离
'showMarker': false,//是否显示定位点
'markerOptions': {//自定义定位点样式,同Marker的Options
'offset': new AMap.Pixel(-18, -36),
'content': '<img src="https://a.amap.com/jsapi_demos/static/resource/img/user.png" style="width:36px;height:36px"/>'
},
'showCircle': false,//是否显示定位精度圈
'circleOptions': {//定位精度圈的样式
'strokeColor': '#0093FF',
'noSelect': false,
'strokeOpacity': 0.5,
'strokeWeight': 1,
'fillColor': '#02B0FF',
'fillOpacity': 0.25
}
}
isLoadingMap.value = true
// 地图定位
AMap.plugin(["AMap.Geolocation"], function () {
var geolocation = new AMap.Geolocation(options);
geolocation.getCurrentPosition((status, result) => {
if (status == 'complete') {
lngLatArr = [+result.position.lng, +result.position.lat]
isLoadingMap.value = false
resolve(true)
} else {
isLoadingMap.value = false
lngLatArr = [116.397755, 39.903179] //定位失败,默认北京天安门
resolve(true)
}
})
});
})
}
if (lngLatArr.length == 0) {
await getCurrentPosition()
}
var marker, map = new AMap.Map("gdMapContainer", {
viewMode: "3D",
resizeEnable: true,
center: lngLatArr,
zoom: 16,
});
// 实例化点标记
function addMarker() {
if (!marker) {
marker = new AMap.Marker({
// icon: "//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-default.png",
icon: '/src/assets/images/marker.png',
position: lngLatArr,
offset: new AMap.Pixel(-13, -30),
draggable: true,
});
marker.setMap(map);
}
}
addMarker()
//拖动坐标获取新坐标
marker.on('dragend', function () {
let position = [marker.getPosition().lng, marker.getPosition().lat] //位置的经纬度
new AMap.plugin("AMap.Geocoder", () => {
const geocoder = new AMap.Geocoder({
// city: "028" //指定进行编码查询的城市,支持传入城市名、adcode 和 citycode
});
geocoder.getAddress(position, (status, result) => {
if (status === "complete" && result.info === "OK") {
word.value = result.regeocode.formattedAddress
cityCode.value = result.regeocode.addressComponent.citycode
searchMap()
}
});
});
})
})
}
// 搜索地址
function searchMap() {
AMapLoader.load({
key: keyInfo.key,
version: '2.0'
}).then((AMap) => {
var keywords = word.value
AMap.plugin(['AMap.AutoComplete', 'AMap.PlaceSearch'], function () {
var autoOption = {
// city: cityCode.value ?? '020', //默认搜索广州
pageSize: 99,
pageIndex: 1,
datatype: 'poi',
extensions: "all",
citylimit: false //是否限制只搜索当前市的地址
}
var placeSearch = new AMap.PlaceSearch(autoOption)
placeSearch.search(keywords, function (status, result) {
if (result.info == 'OK') {
poiList.value = result.poiList.pois
}
})
})
})
}
// 移动修改定位点
function editMarker(arr) {
AMapLoader.load({
key: keyInfo.key,
version: '2.0'
}).then((AMap) => {
var marker, map = new AMap.Map("gdMapContainer", {
viewMode: "3D",
resizeEnable: true,
center: arr,
zoom: 16,
});
// 实例化点标记
function addMarker() {
if (!marker) {
marker = new AMap.Marker({
// icon: "//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-default.png",
icon: "/src/assets/images/marker.png",
position: arr,
offset: new AMap.Pixel(-13, -30),
draggable: true,
});
marker.setMap(map);
}
}
addMarker()
marker.on('dragend', function () {//拖动坐标获取新坐标
let position = [marker.getPosition().lng, marker.getPosition().lat] //位置的经纬度
new AMap.plugin("AMap.Geocoder", () => {
const geocoder = new AMap.Geocoder({
// city: "028" //指定进行编码查询的城市,支持传入城市名、adcode 和 citycode
});
geocoder.getAddress(position, (status, result) => {
if (status === "complete" && result.info === "OK") {
cityCode.value = result.regeocode.addressComponent.citycode
word.value = result.regeocode.formattedAddress
searchMap()
}
});
});
})
})
}
// 下拉选择地址
const activeId = ref('')
function selectPoi(item, index) {
activeId.value = item.id
poiList.value.map(el => {
if (el.id == item.id) {
searchMapInfo.value = {
latitude: el.location.lat,
longitude: el.location.lng,
storeAddress: el.address,
cityCode: el.citycode
}
editMarker([el.location.lng, el.location.lat])
}
})
}
//更新地址
function setMap1() {
if (!searchMapInfo.value.latitude || searchMapInfo.value.longitude == '') {
message.warning('请选择一个地址');
return
}
let data = {
id: detailData.value.id,
...searchMapInfo.value
};
updateStoreAddress(data).then(res => {
message.success('店铺地址更新成功')
showMap1.value = false;
word.value = ''
poiList.value = []
getHeaderDetailData();
})
}
function showMapBtn1() {
mapForm.value = {};
showMap1.value = true;
searchMapInfo.value = {};
initMap(detailData.value)
}
}
})
</script>
腾讯地图
使用iframe来展示地图区域。
腾讯自带搜索栏,地址添加属性search=1。
此处是写死key。
<template>
<div @click="showMapBtn1" class="addressBox">
<span :class="{ 'mr-8px': detailData.storeAddress }">{{ detailData.storeAddress }}</span>
<img class="imgs" src="/src/assets/images/editAddress.png" style="width: 16px;height: 16px;" />
</div>
<a-modal v-model:visible="showMap1" width="50%" title="地图选点" @ok="setMap1">
<iframe width="100%" style="height: 60vh; width: 100%; border: none;" :src="map_src"></iframe>
</a-modal>
</template>
<script>
import AMapLoader from "@amap/amap-jsapi-loader";
import { Button, message, Modal, Spin} from 'ant-design-vue';
import { getAutonaviKey } from '/@/api/merchant';
export default defineComponent({
name: 'eidtMap',
components: {
Button,
AModal: Modal,
ASpin: Spin,
},
setup() {
// 腾讯地图相关
let searchMapInfo = ref<any>({})
window.addEventListener('message', function (event) {
// 接收位置信息,用户选择确认位置点后选点组件会触发该事件,回传用户的位置信息
var loc = event.data;
if (loc && loc.module == 'locationPicker') {//防止其他应用也会向该页面post信息,需判断module是否为'locationPicker'
searchMapInfo.value = {
latitude: loc.latlng.lat,
longitude: loc.latlng.lng,
storeAddress: loc.poiaddress
}
}
}, false);
let showMap1 = ref(false);
let mapForm = ref<any>({});
let map_src = ref('https://apis.map.qq.com/tools/locpicker?search=1&type=1&key=你的key&referer=你的referer');
//更新地址
function setMap1() {
if (!searchMapInfo.value.latitude || searchMapInfo.value.longitude == '') {
message.warning('请选择一个地址');
return
}
let data = {
id: detailData.value.id,
...searchMapInfo.value
};
updateStoreAddress(data).then(res => {
message.success('店铺地址更新成功')
showMap1.value = false;
word.value = ''
poiList.value = []
getHeaderDetailData();
})
}
function showMapBtn1() {
mapForm.value = {};
showMap1.value = true;
searchMapInfo.value = {};
}
}
})
</script>