由於趕項目,搜索獲取某個位置信息實現后並未解決點擊地圖也可以獲取相應的位置信息,后來實現,以此記錄:
需求:可以搜索點位,也可以在地圖上點擊獲取位置的詳細信息,並制作成組件
過程:通過查詢發現原來用的搜索組件並不支持給予初始值,自然也無法把點圖上點擊的地點位置信息獲取后顯示在搜索框中,提煉成組件以后也無法回顯,只能用input輸入,再增加搜索后的提示列表來模擬:
代碼如下:
主頁面vue文件
<template>
<div class="contain">
<div v-if="primitiveData.locationName">
搜索:{{primitiveData.name}},詳細地址為:{{primitiveData.locationName}},經度:{{primitiveData.longitude}},緯度:{{primitiveData.latitude}}
</div>
<div>
<el-input v-model="location" placeholder="定位" readonly @click.native="siteDialog=true"></el-input>
</div>
<Site :dialogShow.sync="siteDialog" @locationSure="locationSure" :primitiveData="primitiveData"></Site>
</div>
</template>
<script>
import Site from '@/components/site'
export default {
name: 'AMapDemo',
components: {
Site
},
data() {
return {
location:'',
siteDialog:false,
primitiveData:{}
}
},
methods: {
locationSure(val) {
// 定位地址
console.log(val)
this.location = val.name
this.primitiveData =val
},
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="scss" scoped>
.amap-demo {
width: 100%;
height: 600px;
position: relative;
}
.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;
}
}
}
</style>
組件vue頁面:
<template>
<div v-if="dialogShow">
<el-dialog title="定位" width="520px" :before-close="hide" :visible.sync="dialogShow" :close-on-click-modal="false"
append-to-body class="site">
<el-row class="app-container home">
<el-col :span="24" class="box">
<el-amap ref="map" vid="amapDemo" :center="center" :zoom="zoom" class="amap-demo" :events="events">
<el-amap-marker :position="center" key="100"></el-amap-marker>
</el-amap>
<div class="searchBox">
<el-input v-model="inputValue" placeholder="搜索地名或者地址" id="tipinput" prefix-icon="el-icon-search"
class="searchInput"></el-input>
<div class="searchContainer">
<div class="searchItem" v-for="(item, index) in list" :key="item.id"
:style="activeIndex === index && 'background: #ecf5ff'" @click="itemChange(item, index)">
<div>{{item.name}}</div>
<div style="color:#999;font-size:12px;">{{item.address}}</div>
</div>
</div>
</div>
</el-col>
</el-row>
<div slot="footer" class="dialog-footer">
<el-button @click="hide">取 消</el-button>
<el-button type="primary" @click="save">確 定</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
export default {
name: "site",
components: {},
props: {
dialogShow: {},
primitiveData: {}
},
data() {
return {
tabIndex: '',
list: [],
activeIndex: '',
zoom: 12,
center: [118.02, 24.48],
searchOption: {
citylimit: false
},
inputValue: '',
searchResult: {
address: '',
latitude: '',
longitude: '',
name: '',
type: '',
country: '',
province: '',
city: '',
area: '',
township: '',
street: '',
neighborhood: '',
locationName: ''
},
events: {
// 地圖上的點擊事件
click: (e) => {
this.$nextTick(() => {
let that = this
that.position = [e.lnglat.lng, e.lnglat.lat]
let geocoder = new AMap.Geocoder({});
geocoder.getAddress(that.position, function(status, result) {
if (status === 'complete' && result.info === 'OK') {
let obj = result.regeocode.addressComponent
that.inputValue = obj.province + obj.city + obj.district + obj.township + obj.street +
obj.streetNumber + (obj.building || '')
}
});
})
}
}
}
},
computed: {},
watch: {
dialogShow(val) {
if (val) {
this.inputValue = this.primitiveData.name
this.list = []
}
},
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 || ''
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 === 'complete' && result.info === 'OK') {
let obj = result.regeocode.addressComponent
that.searchResult.locationName = obj.province + obj.city + obj.district + obj.township + obj.street +
obj.streetNumber + (n.address || obj.building || '')
}
});
},
initMapByInput() {
let that = this
// 自動搜索插件
AMap.plugin('AMap.Autocomplete', () => {
let autoOptions = {
city: '全國'
};
let autoComplete = new AMap.Autocomplete(autoOptions)
autoComplete.search(that.inputValue, function(status, e) {
if (status === 'complete' && e.info === 'OK') {
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.list = 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 === 'complete' && result.info === 'OK') {
let obj = result.regeocode.addressComponent
that.searchResult.locationName = obj.province + obj.city + obj.district + obj.township +
obj.street + tip.address
}
});
} else {
that.list = []
that.searchResult = []
}
}
});
});
},
// 保存提交
save() {
this.$emit('locationSure', this.searchResult)
this.$emit('update:primitiveData', this.searchResult)
this.hide()
},
// 關閉彈框
hide() {
this.dataShow = false
this.inputValue = ''
this.$emit("update:dialogShow", false)
},
},
};
</script>
<style lang="scss" scoped>
ul,
dl {
padding: 0;
margin: 0;
list-style-type: none;
}
::-webkit-scrollbar {
display: none;
}
.amap-demo {
width: 100%;
height: 600px;
position: relative;
}
.site /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%;
height: 230px;
border-radius: 10px 10px 0 0;
background: #fff;
font-size: 13px;
color: #333333;
position: absolute;
bottom: 0;
left: 0;
z-index: 999;
margin-top: 10px;
overflow: hidden;
.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;
justify-content: space-between;
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>
地圖的引入可以參考上一篇,由於vue-amap是根據element的框架開發,為了方便也引入了element ui。詳細代碼下載:https://gitee.com/yuexiayunsheng/amapdemo
