文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Vue如何开发高德地图应用

2023-06-20 13:13

关注

这篇文章主要为大家展示了“Vue如何开发高德地图应用”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Vue如何开发高德地图应用”这篇文章吧。

异步加载

因为使用 js sdk 应用,脚本文件本身体积很大,所以要注意下加载的白屏时间,解决用户体验问题,目前绝大部分产品应用都是 SPA 单页面应用系统,所以我封装一个异步加载的方法:

const loadScripts = async scripts => {  const get = src => {    return new Promise(function(resolve, reject) {      const el = document.createElement('script')      el.addEventListener('load', function() {        resolve(src)      }, false)      el.addEventListener('error', function() {        reject(src)      }, false)      el.id = src.id      el.src = src.url      document.getElementsByTagName('body')[0].appendChild(el) || document.getElementsByTagName('head')[0].appendChild(el)    })  }  const myPromises = scripts.map(async script => {    if (document.getElementById(script.id) === null) {      return await get(script)    }  })  return await Promise.all(myPromises)}export default loadScripts

这个方法在加载脚本的时候先去判断页面是否存在该脚本,如果存在就不会加载第二次,然后再利用加载完毕回调执行相关方法。

封装组件

如果系统中有多个页面需要地图应用业务,那么需要封装一个通用型的地图组件,提高项目可维护性,我这边就简单的封装下地图应用:

<template>  <div    :style="{      width: width,      height: height    }"    class="amap-container"  >    <div ref="amap" class="amap">      <slot />    </div>  </div></template><style lang="scss" scoped>    .amap-container {    .amap {        width: 100%;        height: 100%;    }    }</style>

指定一个地图应用容器,外面包裹一层指定高宽,高宽作为外部变量传入,业务逻辑如下:

import loadScripts from '@/loadScripts'export default {  name: 'AMapContainer',  props: {    width: {      require: false,      type: String,      default: '100%'    },    height: {      require: false,      type: String,      default: '600px'    },    options: {      require: false,      type: Object,      default: () => {}    }  },  data: () => ({    amap: null,    amapInfo: {      key: 'xxxxxxxxxxxxxx'    }  }),  created() {    this.initAMap()  },  beforeDestroy() {    // 销毁地图    if (!this.amap) {      return    }    this.amap.destroy()    this.amap = null  },  methods: {    initAMap() {      loadScripts([{        id: 'ampa',        url: `https://webapi.amap.com/maps?v=2.0&key=${this.amapInfo.key}&plugin=AMap.PolygonEditor`      }]).then(() => {        this.amap = new window.AMap.Map(this.$refs['amap'], this.options)        this.$emit('map', this.amap, window.AMap)      })    }  }}

应用加载的时候初始化地图容器:异步加载高德地图 js sdk 然后回调方法里进行实例化地图应用,并且把地图实例化的对象传入 $emit 事件里,方便父类组件需要。另外注意要在销毁生命周期里对地图应用进行销毁,否则会占用大量的系统内存。

使用组件

封装好组件后就可以在对应的页面进行引入组件使用即可:

<template>    <amap-container height="100%" :options="amapOptions" @map="getAMapData" /></template><script>    import AMap from '@/components/AMap'    export default {        name: 'AMapDemo',        components: {            'amap-container': AMap        },        data: () => ({            amapOptions: {                zoom: 14,                resizeEnable: true,                viewMode: '3D',                mapStyle: 'amap://styles/normal'            },            AMap: null, // 地图对象            amap: null // 当前地图实例        }),        methods: {                        getAMapData(amap, AMap) {                // 从组件获取地图 amap 对象                this.amap = amap                // 从组件获取地图 AMap 静态对象                this.AMap = AMap            }        }    }</script>

然后在上面基础上展开相关业务。对于地图应用来说,最核心的数据就是地图应用中的坐标,无论是地图的标记元素,折线元素(轨迹等),绘制图元素等,只需要获取对应的经纬度数据存到数据库即可,至于怎么获取这边不再详述。

自定义界面最佳实践

之前制作的地图应用,在标记的详细界面(选择某个标记左键打开界面),这个界面是需要传入原生 document 对象,但是在 vue 对象里面不符合这种写法,所以导致之前很多系统都是花大量的时间去编写 dom 结构,甚是头疼,后续为了解决这个问题,vue 是否有相关方法挂载组件获取真实的 document 对象,查阅相关文档后,确实有这个 api : Vue.extend,利用这个 api 挂载组件对象即可得到实例化组件的对象。

import ContextCard from './components/ContextCard'// 创建标记const marker = new this.AMap.Marker({  map: this.amap,  position: [119.058904, 33.537069]})// 绑定点击事件marker.on('click', this.markerInfoWindow)// 点击打开弹窗const markerInfoWindow = () => {  // 引入 Vue 组件构造器实例化  const ContextCardContent = Vue.extend(ContextCard)  // 挂载组件  const contextCardContent = new ContextCardContent().$mount()  // 实例化窗口对象  this.amapInfoWindow = new this.AMap.InfoWindow({    isCustom: true,    content: contextCardContent.$el,    offset: new this.AMap.Pixel(0, -40)  })  // 打开窗口  this.amapInfoWindow.open(this.amap, marker.getPosition())  // 监听组件事件关闭窗口  contextCardContent.$on('closeWindow', () => this.amapInfoWindow.close())}

ContextCard.vue 组件:

<template>  <el-card class="context-box-card box-card">    <div slot="header" class="header">      <span>卡片名称</span>      <el-button type="text" class="close-btn" @click="closeWindow">关闭</el-button>    </div>    <div v-for="o in 4" :key="o" class="text item">      {{ '列表内容 ' + o }}    </div>  </el-card></template><script>export default {  name: 'AMapContextCard',  methods: {    closeWindow() {      this.$emit('closeWindow')    }  }}</script><style lang="scss" scoped>.context-box-card {  width: 320px;  height: 200px;  .header {    display: flex;    justify-content: space-between;    align-items: center;  }  ::v-deep .el-card__header {    padding: 5px 20px;  }}</style>

上面就是一个标点点击打开标记弹窗的详细信息,利用 Vue.extend 构造器进行实例化组件。这样很大程度上提高项目健壮性。

import Vue from "vue";import App from "./App.vue";import Element from "element-ui";import "normalize.css/normalize.css";import "element-ui/lib/theme-chalk/index.css";Vue.config.productionTip = false;Vue.use(Element);new Vue({  render: (h) => h(App)}).$mount("#app");

以上是“Vue如何开发高德地图应用”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注编程网行业资讯频道!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯