文章详情

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

请输入下面的图形验证码

提交验证

短信预约提醒成功

Vue开发高德地图应用的最佳实践

2024-04-02 19:55

关注

前言

之前做不过不少关于地图交互的产品系统,目前国内主流的地图应用 SDK 只有几家:高德、百度和腾讯。所以个人觉得在 PC 应用上高德地图开发相对好一些,至少体验起来没有很明显的坑。这篇文章算是总结下开发地图应用总结吧。

异步加载

因为使用 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开发高德地图应用的文章就介绍到这了,更多相关Vue高德地图应用内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

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

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

软考中级精品资料免费领

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

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

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

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

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

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

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