首页 > 其他分享 >vue3 高德地图弹窗选址功能

vue3 高德地图弹窗选址功能

时间:2023-04-10 14:13:14浏览次数:42  
标签:ps const map vue3 AMap address new 高德 弹窗

import { defineComponent, h } from 'vue'; import AMapLoader from '@amap/amap-jsapi-loader'; import { Input, AutoComplete, Modal, message } from 'ant-design-vue'; // 首先需要引入 Vue3 的 shallowRef 方法(使用 shallowRef 进行非深度监听,因为在 Vue3 所使用的 Proxy 拦截操作会改变 JSAPI 原生对象,所以此处需要区别 Vue2 使用方式对地图对象行非深度监听,否则会出现问题,建议 JSAPI 相关对象采用非响应式的普通对象来存储)。 import { shallowRef } from '@vue/reactivity'; import { debounce } from 'lodash'; import './index.less'; import Service from './service';
export default defineComponent({   name: 'amap',   props: {     visible: {       type: Boolean,       required: true,     },     bindCancel: {       type: Function,       required: true,     },     bindOk: {       type: Function,       required: true,     },     width: {       type: Number,     },   },   components: {     antModal: Modal,     antInput: Input,     antAutoComplete: AutoComplete,   },   data() {     const instance = shallowRef(null);     const map = shallowRef(null);     const marker = shallowRef(null);     const geocoder = shallowRef(null);     const placeSearch = shallowRef(null);     return {       instance,       map,       marker,       geocoder,       placeSearch,       options: [],       value: '',       address: {},     } as any;   },   watch: {     visible(val) {       if (val && !this.instance) {         this.initMap();       }     },   },   methods: {     initMap() {       AMapLoader.load({         key: '******', // 申请好的Web端开发者Key,首次调用 load 时必填         version: '1.4.15', // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15         plugins: ['AMap.ToolBar', 'AMap.Scale', 'AMap.PlaceSearch', 'AMap.Geocoder'], // 需要使用的的插件列表,如比例尺'AMap.Scale'等       })         .then((AMap) => {           this.instance = AMap;           this.geocoder = new AMap.Geocoder({ extensions: 'all' });           this.placeSearch = new AMap.PlaceSearch({ extensions: 'all', pageSize: 15 });           this.map = new AMap.Map('amap', {             //设置地图容器id             viewMode: '3D', //是否为3D地图模式             zoom: 12, //初始化地图级别             animateEnable: false,           });           const ToolBar = new AMap.ToolBar();           const Scale = new AMap.Scale();
          this.map.addControl(ToolBar);           this.map.addControl(Scale);
          const marker = new this.instance.Marker({             icon: 'https://webapi.amap.com/theme/v1.3/markers/n/mark_b.png',             position: [22, 22],             offset: new this.instance.Pixel(-10, -35),             visible: false,           });           this.marker = marker;           this.map.add(marker);
          this.map.on('click', (e) => {             this.setPosition(e.lnglat);           });         })         .catch((e) => {           console.log(e);         });     },     search(str) {       this.placeSearch.search(str, (status, result) => {         if (status === 'complete' && result.info === 'OK') {           this.options = result.poiList.pois.map((ps, idx) => {             const item = (               <div>                 <span>                   {idx + 1}. {ps.name}                 </span>                 <div style={{ fontSize: '13px', color: '#999999' }}>                   地址:{ps.pname}                   {ps.cityname === ps.pname ? undefined : ps.cityname}                   {ps.adname}                   {ps.address}                 </div>               </div>             );             return {               obj: ps,               label: item,               name: ps.name,               value: `${ps.location.lng}-${ps.location.lat}`,             };           });         } else {           this.options = [];         }         //console.log(str, status, result);       });     },     setPosition(posi) {       this.geocoder.getAddress(posi, async (status, result) => {         //console.log(status, result);         if (status === 'complete' && result.info === 'OK') {           const { addressComponent, formattedAddress } = result.regeocode;           const { province, city, district } = addressComponent;           this.address = { province, city, district, detail: formattedAddress };           this.marker.setPosition(posi);           this.marker.show();
          const infoWindow = new this.instance.InfoWindow({             anchor: 'bottom-center',             content: `<div style="padding: 10px;">${result.regeocode.formattedAddress}</div>`,             offset: new this.instance.Pixel(0, -38),           });           infoWindow.open(this.map, posi);           this.address = await this.translateAddress(this.address);           //console.log(this.address);         }       });     },     //获取省市区数据源方法,具体看后端接口,可自定义     async getDataSource(params) {       try {         //这一步主要是获取对应省市区的数据源         const res = await Service.getDataSource(params);         return res;         // return (res.records || []).map((r) => {         //   return { ...r, label: r.codeName, value: r.code };         // });       } catch (e) {         message.error((e as any).message || '获取数据异常');         return [];       }     },     //根据所选省市区翻译code     async translateAddress(address) {       const { province, city, district, detail } = address || {};       //坑:不判断!city,因为存在直辖市的情况,直辖市的city为空,province===city       if (!province || !district) {         return;       }       const provinceSource = await this.getDataSource({ codeType: 'sheng' });       const provinceCode = (provinceSource.find((ps) => ps.label === province) || {}).value;
      const citySource = await this.getDataSource({ codeType: 'shi', sheng: provinceCode });       const cityCode = (citySource.find((ps) => ps.label === (city || province)) || {}).value;
      const districtSource = await this.getDataSource({ codeType: 'qu', shi: cityCode });       const districtCode = (districtSource.find((ps) => ps.label === district) || {}).value;       const addressDetail = detail.replace(`${province}${city}${district}`, '');       address = { ...address, provinceCode, cityCode, districtCode, addressDetail };       return address;     },     onCancel() {       this.bindCancel();     },     onOk() {       if (Object.keys(this.address).length === 0) {         message.warn('请选择一个地址');         return;       }       this.bindOk(this.address);       this.onCancel();     },   },   render() {     return (       <antModal         title="电子地图"         visible={this.visible}         onCancel={() => this.onCancel()}         onOk={() => this.onOk()}         style={{ top: '20px' }}         width={this.width || 800}>         <antAutoComplete           allowClear={true}           onSearch={debounce(this.search, 300)}           onChange={(val) => (this.value = val)}           onSelect={async (val, option) => {             this.value = option.name;             const posi = val.split('-');             this.map.setZoomAndCenter(16, posi);             // this.setPosition(posi);
            const { pname, cityname, adname, address, name } = option.obj;             this.address = { province: pname, city: cityname, district: adname, detail: address + name };             this.marker.setPosition(posi);             this.marker.show();
            const infoWindow = new this.instance.InfoWindow({               anchor: 'bottom-center',               content: `<div style="padding: 10px;">${                 pname + (cityname === pname ? '' : cityname) + adname + address + name               }</div>`,               offset: new this.instance.Pixel(0, -38),             });             infoWindow.open(this.map, posi);             this.address = await this.translateAddress(this.address);             console.log(this.address);           }}           value={this.value}           options={this.options}           style={{ width: '100%' }}         />         <div id="amap"></div>       </antModal>     );   }, });

标签:ps,const,map,vue3,AMap,address,new,高德,弹窗
From: https://www.cnblogs.com/xinyouhunran/p/17169097.html

相关文章

  • vue3 环境搭建部署
    安装node查看版本chenjun@chenjundeMacBook-Airuitest%node-vv18.7.0创建vue项目(⚠️注意项目名称小写)npminitvue@latest运行vue项目 1cd项目2npminstall3npmrundev ......
  • 如何在servlet中写弹窗点击确认时候可以跳转到另一个页面
    流程:登录页面-->注册页面-->注册成功后提示“注册成功”,并且跳转回登录页面。一开始我想着设置回传信息,然后跳转到login.jsp页面中,弹出“注册成功”的信息,但是感觉这个想法不是那么好实现,然后我最后也找到了一个更好的方法,直接在servlet中就可以实现了,只要写出下面的代码即可。......
  • 百度高德地图JS-API学习手记:地图基本设置与省市区数据加载
    无论是百度还是高德地图开发,还是高德地图开发。官方的给的案例启示很多,copy再修改下,就完成了https://lbs.amap.com/api/javascript-api/summary  http://lbsyun.baidu.com/index.php?title=jspopular3.0这个大致看一下,我想。有点GIS基础都能完成地图开发。个人认为百度的文档......
  • 百度高德地图行政区域边界GeoJSON数据获取并绘制行政区域
    highcharts是提供地图数据包的:https://www.highcharts.com/docs/maps/map-collectionechart矢量地图或者地图绘制矢量图层,GeoJSON哪里提供呢?dataV提供数据下载,http://datav.aliyun.com/tools/atlas/#&lat=30.332329214580188&lng=106.75386074913891&zoom=4.5这些数据也是从高......
  • vscode 开发 vue3项目 , src 别名 为 @ ,报错
    https://geekdaxue.co/read/me-note@vue/mydm8l需要设置basicURL然后就生效了{"compilerOptions":{//设置解析非相对模块名称的基本目录"baseUrl":".",//设置模块名到基于baseUrl的路径映射,可以设置路径别名的语法提示"paths":{"@/*......
  • vue3学习第二课:组件和父组件的传递数据给子组件方式props
    1,在conponents目录中新建header.vue<template><div><h1>这是头部组件</h1></div></template>2,在App.vue中添加<template><div><Header></Header><Main></Main><Foote......
  • 学习使用VUE3+Django+GraphQL实现简单的Blog网站
    这周每天花点时间学习使用VUE3+Django+GraphQL的使用,按照RealPython的网站的教程走了一遍,踩了一遍坑.Realpython上的教程使用的是Vue2的Vue-CLI模块,Vue本身已经进化到VUE3,并且推荐使用Vite代替Vue-CLI.我按照教程上的步骤将代码转化为VUE3+Vite+CompositionAPI模式.在这里......
  • Vue3.0学习二
    组合式API:setup在beforecreate之前就执行了。import{ ref,toRefs, toRef,h}from'vue'export  default {props:{name:{type:String}},//setup中使用props中的数据setup(props,context){//propsconsole.log(prop......
  • vue3.0和2.0的区别
    Vue.js是一个渐进式JavaScript框架,Vue.js3.0相比于2.0有以下区别:更快:Vue.js3.0的渲染速度比2.0快了近30%。更小:Vue.js3.0的体积比2.0小了41%。更易维护:Vue.js3.0的代码结构更加清晰,更易于维护。更易于原生:Vue.js3.0的内部实现更加接近原生JavaScript,使得开发者更容易理......
  • 高德地图搜索结果如何导出成excel里?
    地图搜索左边查询的商家如何导出到EXCEL里?解决销售人员一个一个从地图上翻找复制客户信息的低下效率、销售人员就应该专心去做他们擅长的业务营销!经过一段时间的琢磨,经过长时间的反复测试,做出了导出地图商家电话到EXCEL里的系统  操作步骤:1.选择你要采集的省份,城市列表......