|
利用vue-amap实现 能够在搜索栏进行地点搜索、点击地图选择点。
版本:"vue-amap": "^0.5.10"
效果图:


首先申请key
官网教程:准备-入门-教程-地图 JS API | 高德地图API
根据官网教程获取、配置好以后在main.js进行如下操作
main.js
// 高德地图
import VueAMap from 'vue-amap'
Vue.use(VueAMap)
VueAMap.initAMapApiLoader({
key: '445701bd34854887f03c540b449a620f',
plugin: [
'AMap.Autocomplete', // 输入提示插件
'AMap.PlaceSearch', // POI搜索插件
'AMap.Scale', // 右下角缩略图插件 比例尺
'AMap.OverView', // 地图鹰眼插件
'AMap.ToolBar', // 地图工具条
'AMap.Geolocation', // 定位控件,用来获取和展示用户主机所在的经纬度位置
'AMap.MarkerClusterer',
'AMap.Geocoder'
],
uiVersion: '1.0',
v: '1.4.15'
})
Vue.config.productionTip = false
// 开发环境
// window._AMapSecurityConfig = {
// securityJsCode: '安全密钥',
// }
// 生产环境 后台配置的安全密钥地址 详见官方配置文件
window._AMapSecurityConfig = {
serviceHost: `xxx/_AMapService`
}弹窗代码
<template>
<div v-if=&#39;dialogShow&#39;>
<el-dialog title=&#39;选择地址&#39; width=&#39;1200px&#39; :before-close=&#39;hide&#39; :visible.sync=&#39;dialogShow&#39;
:close-on-click-modal=&#39;false&#39;
append-to-body class=&#39;site&#39;>
<div v-if=&#39;dialogShow&#39;>
<div class=&#39;searchBox&#39;>
<div>
<el-input style=&#39;width: 80%&#39; v-model=&#39;inputValue&#39; placeholder=&#39;搜索地名或者地址&#39; id=&#39;tipinput&#39;
prefix-icon=&#39;el-icon-search&#39;
class=&#39;searchInput&#39;></el-input>
<el-button type=&#39;primary&#39; size=&#39;small&#39; @click=&#39;initMapByInput&#39;>查询</el-button>
</div>
<div class=&#39;searchContainer&#39; v-if=&#39;markers.length>0&&searchContainerShow&#39;>
<div class=&#39;searchItem&#39; v-for=&#39;(item, index) in markers&#39; :key=&#39;item.id&#39;
:style=&#34;activeIndex === index && &#39;background: #ecf5ff&#39;&#34; @click=&#39;itemChange(item, index)&#39;>
<div>{{ item.name }}</div>
<div style=&#39;color:#999;font-size:12px;margin-left: 10px&#39; class=&#39;textOverflow&#39;>{{ item.address }}</div>
</div>
</div>
</div>
<div>
<el-amap ref=&#39;map&#39; vid=&#39;amapDemo&#39; :center=&#39;center&#39; :zoom=&#39;zoom&#39; :plugin=&#39;plugin&#39; class=&#39;amap-demo&#39;
:events=&#39;events&#39;>
<el-amap-marker :position=&#39;center&#39; key=&#39;100&#39;></el-amap-marker>
</el-amap>
</div>
</div>
<div slot=&#39;footer&#39; class=&#39;dialog-footer d-flex justify-content-between align-items-center&#39;>
<div style=&#39;font-size: 16px&#39;>所选位置:{{ currentValue }}</div>
<div>
<el-button type=&#39;primary&#39; @click=&#39;save&#39;>确 定</el-button>
<el-button @click=&#39;hide&#39;>取 消</el-button>
</div>
</div>
</el-dialog>
</div>
</template>
<script>
// 引入获取实例
import { AMapManager } from &#39;vue-amap&#39;
let amapManager = new AMapManager()
let Geocoder
export default {
components: {},
props: {
dialogShow: {},
//精度
lng: {},
//维度
lat: {},
primitiveData: {}
},
data() {
const that = this
return {
tabIndex: &#39;&#39;,
currentValue: &#39;&#39;,
searchContainerShow: false,
markers: [],
activeIndex: &#39;&#39;,
zoom: 12,
center: [116.397455, 39.909187],
searchOption: {
citylimit: false
},
resultValue: {},
inputValue: &#39;&#39;,
searchResult: {
address: &#39;&#39;,
latitude: &#39;&#39;,
longitude: &#39;&#39;,
name: &#39;&#39;,
type: &#39;&#39;,
country: &#39;&#39;,
province: &#39;&#39;,
city: &#39;&#39;,
area: &#39;&#39;,
township: &#39;&#39;,
street: &#39;&#39;,
neighborhood: &#39;&#39;,
locationName: &#39;&#39;
},
events: {
// 地图上的点击事件
click: (e) => {
this.$nextTick(() => {
let that = this
that.position = [e.lnglat.lng, e.lnglat.lat]
that.center = [e.lnglat.lng, e.lnglat.lat]//打点
let geocoder = new AMap.Geocoder({})
geocoder.getAddress(that.position, function(status, result) {
if (status === &#39;complete&#39; && result.info === &#39;OK&#39;) {
that.resultValue = result.regeocode.addressComponent
let obj = result.regeocode.addressComponent
let value = obj.province + obj.city + obj.district + obj.township + obj.street +
obj.streetNumber + (obj.building || &#39;&#39;)
that.currentValue = value
}
})
})
this.searchContainerShow = false
}
},
plugin: [
{
enableHighAccuracy: true, //是否使用高精度定位,默认true
timeout: 100, //超过10秒后停止定位,默认:无穷大
convert: true, //自动偏移后的坐标为高德坐标,默认:true
showButton: true, //显示定位按钮,默认:true
buttonPosition: &#39;RB&#39;, //定位按钮停靠位置,默认&#39;LB&#39;,左下角
showMarker: true, //定位成功后在定位到的位置显示标记,默认:true
showCircle: false, //定位成功后用圆圈表示定位精度范围,默认:true
panToLocation: true, //定位成功后将定位到的位置作为地图中心点,默认true
zoomToAccuracy: true, //定位成功后调整地图视野范围使定位位置及精度范围视野内可见,默认:false
extensions: &#39;all&#39;,
pName: &#39;Geolocation&#39;, //AMap-Geolocation 定位插件
events: {
init(o) {
// o 是高德地图定位插件实例
o.getCurrentPosition((status, result) => {
if (result && result.position) {
let obj = result.addressComponent
that.resultValue = result.addressComponent
let value = obj.province || &#39;&#39; + obj.city || &#39;&#39; + obj.district || &#39;&#39; + obj.township || &#39;&#39; + obj.street || &#39;&#39; +
obj.streetNumber + (obj.building || &#39;&#39;)
that.currentValue = value
that.lng = result.position.lng //设置经度
that.lat = result.position.lat //设置纬度
that.center = [that.lng, that.lat] //设置坐标
that.markers.push(that.center) //获取当前定位并存入标记中显示标记点
that.loaded = true //load
that.zoom = 14
that.$nextTick() //页面渲染好后
}
})
}
}
},
//Geocoder编码:根据地理名称来获得地点的经纬度
{
pName: &#39;Geocoder&#39;,
events: {
init: (o) => {
Geocoder = o // o 则是AMap.Geocoder的实例 对外部的Geocoder变量进行赋值,在任何地方就都可以使用
//data里的events中使用了Geocoder
o.getAddress(that.center, function(status, result) { //根据坐标获取位置
if (status === &#39;complete&#39; && result.info === &#39;OK&#39;) {
let obj = result.regeocode.addressComponent
that.resultValue = result.regeocode.addressComponent
let value = obj.province + obj.city + obj.district + obj.township + obj.street +
obj.streetNumber + (obj.building || &#39;&#39;)
that.currentValue = value
}
})
}
}
}]
}
},
computed: {},
watch: {
dialogShow(val) {
if (val) {
if (this.lng && this.lat) {
this.center[0] = this.lng
this.center[1] = this.lat
}
this.inputValue = this.primitiveData.name
this.markers = []
}
},
inputValue(value) {
if (value) {
// 监听输入内容
// this.initMapByInput()
}
}
},
mounted() {
},
methods: {
itemChange(n, index) {
const that = this
that.activeIndex = index
// 输入后搜索出来的,反地理编码出来的参数有所不同
let lng = n.lng || n.longitude || n.location.lng
let lat = n.lat || n.latitude || n.location.lat
let name = n.name || &#39;&#39;
that.inputValue = name
that.zoom = 13
that.position = [lng, lat]
// that.searchResult.address = n.address
// that.searchResult.latitude = lat
// that.searchResult.longitude = lng
// that.searchResult.name = name
let geocoder = new AMap.Geocoder({})
geocoder.getAddress(that.position, function(status, result) {
if (status === &#39;complete&#39; && result.info === &#39;OK&#39;) {
let obj = result.regeocode.addressComponent
that.resultValue = result.regeocode.addressComponent
// that.searchResult.locationName = obj.province + obj.city + obj.district + obj.township + obj.street +
// obj.streetNumber + (n.address || obj.building || &#39;&#39;)
that.currentValue == obj.province + obj.city + obj.district + obj.township + obj.street +
obj.streetNumber + (n.address || obj.building || &#39;&#39;)
}
})
this.searchContainerShow = false
},
initMapByInput() {
let that = this
// 自动搜索插件
AMap.plugin(&#39;AMap.Autocomplete&#39;, () => {
let autoOptions = {
city: &#39;全国&#39;
}
let autoComplete = new AMap.Autocomplete(autoOptions)
autoComplete.search(that.inputValue, function(status, e) {
if (status === &#39;complete&#39; && e.info === &#39;OK&#39;) {
if (e.tips && e.tips.length > 0) {
let tips = e.tips.filter((i) => {
return i.location && i.address.length > 0
})
let tip = tips[0]
that.center = [tip.location.lng, tip.location.lat]
that.zoom = 13
that.position = [tip.location.lng, tip.location.lat]
that.markers = tips
// that.searchResult.address = tip.address
// that.searchResult.latitude = tip.location.lat
// that.searchResult.longitude = tip.location.lng
// that.searchResult.name = tip.name
let geocoder = new AMap.Geocoder({})
geocoder.getAddress(that.position, function(status, result) {
if (status === &#39;complete&#39; && result.info === &#39;OK&#39;) {
let obj = result.regeocode.addressComponent
that.resultValue = result.regeocode.addressComponent
// that.searchResult.locationName = obj.province + obj.city + obj.district + obj.township +
// obj.street + tip.address
that.currentValue = obj.province + obj.city + obj.district + obj.township + obj.street + tip.address
}
})
that.searchContainerShow = true
} else {
that.markers = []
that.searchResult = []
}
}
})
})
},
// 保存提交
save() {
if (this.center.length == 0 || !this.currentValue) {
return this.$message.warning(&#39;选择的地点有误,请重新选择&#39;)
}
this.$emit(&#39;locationSure&#39;, { name: this.currentValue, value: this.center, address: this.resultValue })
this.$emit(&#39;update:primitiveData&#39;, this.searchResult)
this.hide()
},
// 关闭弹框
hide() {
this.dataShow = false
this.inputValue = &#39;&#39;
this.zoom = 12
this.center = [116.397455, 39.909187]
this.$emit(&#39;update:dialogShow&#39;, false)
}
}
}
</script>
<style lang=&#39;scss&#39; scoped>
ul,
dl {
padding: 0;
margin: 0;
list-style-type: none;
}
::-webkit-scrollbar {
display: none;
}
.amap-demo {
width: 100%;
height: 600px;
position: relative;
}
.site ::v-deep {
.el-dialog__body {
padding: 0;
border-bottom: 1px solid #E4E4E4;
}
.app-container {
padding: 0;
}
.search-box {
height: 35px;
margin: 10px auto;
width: calc(100% - 20px);
// border-radius:16px;
box-shadow: none;
background: #ffff;
border: 1px solid #e6e6e6;
.search-box-wrapper {
input {
background: #fff;
padding-left: 20px;
}
.search-btn {
color: #2A67FE;
width: 90px;
height: 20px;
box-sizing: border-box;
border-left: 1px solid #D7D7D7;
}
}
}
}
.searchBox {
width: 100%;
background: #fff;
font-size: 13px;
color: #333333;
position: absolute;
top: 30px;
left: 0;
z-index: 999;
margin-top: 10px;
.searchContainer {
height: 180px;
margin-top: 10px;
overflow-y: auto;
width: 100%;
padding: 0 10px;
box-sizing: border-box;
}
.searchItem {
color: #333;
font-size: 13px;
text-align: left;
padding: 7px 10px;
display: flex;
border-bottom: 1px solid #e6e6e6;
cursor: pointer;
}
}
::v-deep .el-vue-search-box-container .search-tips {
width: 100%;
top: 100%;
max-height: 190px;
overflow: auto;
}
.active {
background: #DBE5F2;
}
.searchInput {
margin: 0px 10px;
background: #F7F8FA;
border-radius: 16px;
margin-top: 5px;
height: 32px;
width: calc(100% - 20px);
box-sizing: border-box;
}
</style>
弹窗使用
<Point :dialogShow.sync=&#39;siteDialog&#39; :lng=&#39;form.lng&#39; :lat=&#39;form.lat&#39; @locationSure=&#39;locationSure&#39;
:primitiveData=&#39;primitiveData&#39;></Point>
locationSure(val) {
// 定位地址
this.$set(this.form, &#39;address&#39;, val.name)
// this.form.address = val.name
this.primitiveData = val.value
this.form.province = val.address.province
this.form.city = val.address.city ? val.address.city : val.address.province
this.form.district = val.address.district
this.form.lng = val.value[0]
this.form.lat = val.value[1]
}, |
|