需要 & 图例
题目性能分为2局部的需要:
- 【原需要】填写地址:省市区(下拉)+详情(输出),
【新需要】原需要放弃不变,然而减少快捷方式抉择地址,a.减少地图搜索选中后 回填地址 b.罕用地址/历史地址 列表,选中后 回填地址;
图示阐明:
所有图示案例均为代码性能展现用,不思考好看性。
图示1:
图示2:
- 天文编码:地址转为经纬度;逆天文编码:经纬度转为地址;
【需要】:地图关上中心点默认在ip所在的城市;依据历史GPS数据展现车辆的历史轨迹信息,点击轨迹点展现信息窗体,右侧展现中显示以后车辆的所在的经纬度对应的具体地址;
图示3:(中心点默认在ip所在的城市)
图示4:(依据GPS数据展现车辆历史轨迹,基于后端返回的数据展现)
图示5:(前端模仿数据,展现轨迹,点击展现信息窗体,右侧展现逆天文编码信息)
图示6:(依据地址信息转为经纬度,标记在地图上)
main.js
import VueAMap from 'vue-amap'; // 命名尽量与AMap做辨别Vue.use(VueAMap); VueAMap.initAMapApiLoader({ key: 'your key', plugin: [ "AMap.Autocomplete", "AMap.PlaceSearch", "AMap.Scale", "AMap.ToolBar", "AMap.OverView", 'AMap.MapType', 'AMap.PolyEditor', 'AMap.CircleEditor', "AMap.Geolocation", "AMap.Geocoder", "AMap.CitySearch", ], v: '1.4.15', uiVersion: "1.1"});window._AMapSecurityConfig = { securityJsCode: 'your security js code',}
构造以图例1、2 为根底,其余的性能仅以逻辑为主,以阐明为准
所有款式代码均省略
省市区下拉是通过拜访后端接口,这里须要将地图选点中取得的省市区的名字传给后端,失去下拉须要的codes
罕用/历史 选点列表是通过后端接口取得,接口逻辑略,只展现数据结构
map-dialog.vue
template
<!-- 弹窗相干代码略 --><div class="flex"> <!-- 右边 --> <el-amap vid="amapContainer" :center="amap.center" :plugin="amap.plugin" :zoom="amap.zoom" :zoomEnable="true" class="amap" > <!-- 搜寻性能 --> <el-amap-search-box :search-option="searchOption" :on-search-result="onSearchResult" class="search-box" v-if="params.show" > </el-amap-search-box> <!-- 搜寻后失去的点,可拖拽从新选点,点击确认选点 --> <el-amap-marker :clickable="true" :draggable="true" :events="amap.events" :position="amap.marker" /> </el-amap> <!-- 左边 --> <el-tabs v-model="activeName" type="border-card"> <el-tab-pane label="罕用" name="first"> </el-tab-pane> <el-tab-pane label="历史" name="second"> </el-tab-pane> <el-table :data="dataList" border height="100%"> <el-table-column label="省市区"> <template slot-scope="scope"> <span>{{ scope.row.province+scope.row.city+scope.row.district }}</span><br> </template> </el-table-column> <el-table-column label="具体地址" prop="address"></el-table-column> <el-table-column label="操作" width="60"> <template slot-scope="scope"> <span class="blue" @click="selectData(scope.row)">抉择</span> </template> </el-table-column> </el-table> </el-tabs></div>
script
import { GET_CITYS_CODES } from '@/api/xx/index.js'; // 用地图失去的省市区名称换省市区下拉codesexport default { props: { params: { type: Object, default: {}, }, }, data() { let self = this; return { activeName: "first", amap: { zoom: 9, center: [0, 0], plugin:['ToolBar'], marker: [0, 0], events: { click(e) { self.markerClick(e) }, // 选点点击事件 dragend(e) { self.dragEnd(e) }, // 选点拖拽事件 } }, searchOption: { city: '', citylimit: true }, // dataList原本是后端接口取得,这里不重要,只作数据结构展现 dataList: [{ province: "四川省", city: "成都市", district: "高新区", address: "仁和街阿斯顿路250号", codes: ['510000', '510100', '510107'] }], obj: {}, addr: "" } }, methods: { // 能够放在专门的utils文件中,这里为了不便展现,放在methods里 // 获取以后ip所在城市 getCurrentCity() { return new Promise((resolve, reject) => { let city; AMap.plugin('AMap.CitySearch',function(){ city = new AMap.CitySearch() }) city.getLocalCity(function (status, result) { if (status === 'complete' && result.info === 'OK') { resolve(result.bounds.oc) } else { reject('未检测到该地址') } }); }) }, // 能够放在专门的utils文件中,这里为了不便展现,放在methods里 // 逆天文编码:经纬度转为地址; getPositionByLonLats(lnglat) { return new Promise((resolve, reject) => { let geocoder; AMap.plugin('AMap.Geocoder',function(){ geocoder = new AMap.Geocoder() }) geocoder.getAddress(lnglat, function (status, result) { if (status === 'complete' && result.info === 'OK') { resolve(result.regeocode) } else { reject('未检测到该地址') } }); }) }, // 能够放在专门的utils文件中,这里为了不便展现,放在methods里 // 天文编码:地址转为经纬度(与逆天文编码相似,这里不在演示调用) getPositionByAddr(addr) { return new Promise((resolve, reject) => { let geocoder; AMap.plugin('AMap.Geocoder',function(){ geocoder = new AMap.Geocoder() }) geocoder.getLocation(addr, function (status, result) { if (status === 'complete' && result.geocodes.length) { resolve(result.geocodes[0].location) } else { reject('未检测到该地址') } }); }) }, // 弹窗open事件:中心点默认在设在ip所在地址 setData() { this.getCurrentCity().then((res) => { this.amap.center = []; this.amap.center.push(res.lng, res.lat); }) }, // 点击搜寻列表后果 // 留神:返回的后果是数组,默认选中第一个,作为点坐标 async onSearchResult(pois) { let self = this; await this.getPositionByLonLats([pois[0].lng, pois[0].lat]).then((res) => { self.obj = { ...res.addressComponent }; self.addr = res.formattedAddress; }).catch((err) => { errorMsg(err); return }) self.amap.center = []; self.amap.center.push(pois[0].lng, pois[0].lat); self.amap.marker = []; self.amap.marker.push(pois[0].lng, pois[0].lat); self.amap.zoom = 18; }, // 点坐标拖拽完结 dragEnd(e) { let self = this; // self.getPositionByLonLats([e.lnglat.lng, e.lnglat.lat]).then((res) => { self.obj = { ...res.addressComponent }; self.addr = res.formattedAddress; }).catch((err) => { errorMsg(err); return }) }, // 点击点坐标,是否确认抉择 markerClick() { let self = this; self.$confirm(`是否确认抉择【${this.addr}】?`, "确认抉择", { closeOnClickModal: false, cancelButtonClass: "cancel-btn", confirmButtonClass: "delete-btn", }).then(() => { let a = self.obj.province; let b = self.obj.city; let c = self.obj.district; // 将点坐标省市区名称传给后端,获取省市区下拉codes // 留神:直辖市,高德不会返回市名称,后端要求,直辖市 省市同名 GET_CITYS_CODES([a, b?b:a, c]).then((res) => { if (res.code === 10000) { let info = { address: self.obj.township+self.obj.street+self.obj.streetNumber, codes: res.result } // 将确认信息传给父组件 self.cancel(info); } }); }) .catch(() => {}); }, // 罕用/历史列表 抉择按钮 selectData(data) { let info = { address: data.address, codes: data.codes } // 将抉择信息传给父组件 this.cancel(info); },
其余性能的
template
// 构造与后面的template相似,这里只保留el-amap<el-amap vid="amapContainer2" :center="amap.center" :plugin="amap.plugin" :zoom="amap.zoom" :zoomEnable="true" class="amap" > <!-- 轨迹 --> <el-amap-polyline :stroke-weight="6" :path="amap.path" line-join="round" stroke-color="#00BD00" /> <!-- 点 --> <el-amap-marker v-for="(item, i) in pathData" :key="i+Math.random()" :clickable="true" :position="item.marker" :events="{ click(e){markerClick(e)} }" /> <!-- 信息窗体 --> <el-amap-info-window :auto-move="true" :close-when-click-map="true" :is-custom="true" :offset="[-20, -30]" :position="info.marker" :visible="info.visible" v-if="info.visible" > <div id="info-window"> <p>{{ info.waybillNo }}</p> <p>{{ info.plate }}</p> <p>{{ info.phone }}</p> <p>{{ info.address }}</p> </div> </el-amap-info-window></el-amap>
script
data() { return { // 其余相似的略 info: {}, // 信息窗体 infoList: [] // 信息窗体汇合 }},methods: { // 点击坐标点弹出 信息窗体 markerClick(e) { let self = this; // 第一次点击 才给所有的信息窗体赋值(为了演示不便放在这里,赋值操作依据理论需要失常操作) if (self.infoList.length !== self.pathData.length) { for (let i = 0; i < self.pathData.length; i++) { let obj = {...self.pathData[i]}; obj.visible = false self.infoList.push(obj); } // 切换信息窗体手动敞开所有窗体的visible } else { for (let i = 0; i < self.infoList.length; i++) { self.infoList[i].visible = false } } // 清空上一个信息窗体的信息 self.info = {}; let arr = [e.target.w.position.lng, e.target.w.position.lat]; let index = self.pathData.findIndex(i => i.marker.toString() === arr.toString()); this.$nextTick(() => { self.info = self.infoList[index]; self.$set(self.info, 'visible', true); }) },}