父组件引用高德地图:

 1 <template>
2 <div class="wrapper">
3 <div class="box">
4 <div class="form-box">
5 <el-form
6 label-position="top"
7 :inline="true"
8 :model="addDeviceForm"
9 ref="addDeviceFormRef"
10 :rules="rules"
11 >
12 <el-form-item label="设备安装位置" prop="indatallAddress">
13 <el-input
14 @click="showMap"
15 :suffix-icon="MapLocation"
16 v-model="addDeviceForm.indatallAddress"
17 />
18 </el-form-item>
19 <el-form-item label="设备经度" prop="longitude">
20 <el-input-number
21 disabled
22 :controls="false"
23 v-model="addDeviceForm.longitude"
24 placeholder="请输入经度"
25 />
26 </el-form-item>
27 <el-form-item label="设备纬度" prop="latitude">
28 <el-input-number
29 disabled
30 :controls="false"
31 v-model="addDeviceForm.latitude"
32 placeholder="请输入纬度"
33 />
34 </el-form-item>
35 </el-form>
36 </div>
37 </div>
38 </div>
39 <!-- 地图组件 -->
40 <gao-amap
41 :isShow="amapVisible"
42 :defaultAddress="defaultAddress"
43 :defaultPoint="defaultPoint"
44 @getPosition="getPosition"
45 ></gao-amap>
46 </template>
47
48 <script setup>
49 import { ref } from 'vue'
50 import { ElMessage } from 'element-plus'
51 import { useStore } from 'vuex'
52 import { MapLocation } from '@element-plus/icons-vue'
53 import GaoAmap from '@/components/Amap'
54
55 const store = useStore()
56
57 const addDeviceForm = ref({
58 indatallAddress: '',
59 longitude: null,
60 latitude: null,
61 })
62
63 const amapVisible = ref(false)
64 const defaultAddress = ref('')
65 const defaultPoint = ref([])
66 const showMap = () => {
67 defaultAddress.value = addDeviceForm.value.indatallAddress
68 defaultPoint.value = [
69 addDeviceForm.value.longitude,
70 addDeviceForm.value.latitude
71 ]
72 amapVisible.value = true
73 }
74 const getPosition = (infoObj) => {
75 amapVisible.value = false
76 if (infoObj.address) {
77 addDeviceForm.value.indatallAddress = infoObj.address
78 addDeviceForm.value.longitude = infoObj.point[0]
79 addDeviceForm.value.latitude = infoObj.point[1]
80 }
81 }
82
83 </script>

子组件封装高德地图:

<template>
<el-dialog
title="选择地点"
width="740px"
class="select-map-dialog"
v-model="dialogShow"
:close-on-click-modal="false"
:modal-orgend-to-body="false"
:append-to-body="true"
@close="cancel"
>
<div class="amap-box">
<el-input
clearable
id="keyword"
v-model="tipInput"
placeholder="关键词搜索"
:prefix-icon="Search"
></el-input>
<div id="custom-amap"></div>
<div class="info-list" v-if="address">
<div class="info-item">已选择地点:{{ address }}</div>
<div class="info-item">地点经纬度:{{ point }}</div>
</div>
</div>
<template #footer>
<div class="dialog-footer">
<button class="btn btn-deault" @click="handelSave">确定</button>
<button class="btn btn-plain" @click="cancel">取消</button>
</div>
</template>
</el-dialog>
</template> <script setup>
import { ref, onUnmounted, watch, computed, nextTick } from 'vue'
import { ElMessage } from 'element-plus'
import AMapLoader from '@amap/amap-jsapi-loader'
import { Search } from '@element-plus/icons-vue' const map = ref(null) // 地图对象
const address = ref('') // 地址
const point = ref([]) // 地址对应的经纬度信息 const marker = ref('') // 地图标记
const geocoder = ref('') // 地址解析(正向) const tipInput = ref('') // 检索关键字
const autoComplete = ref(null)
const placeSearch = ref(null) const props = defineProps({
defaultAddress: {
type: String,
default: ''
},
defaultPoint: {
type: Array
},
isShow: {
type: Boolean,
default: false
}
}) const emits = defineEmits(['update:isShow', 'getPosition'])
const dialogShow = computed({
get: () => props.isShow,
set: (value) => {
emits('update:isShow', value)
}
})
watch(
() => dialogShow,
async () => {
await nextTick()
// 初始化地图页面
initMap()
},
{ deep: true },
{ immediate: true }
) // 初始化地图页面
const initMap = () => {
AMapLoader.load({
key: 'c6f04d87fd44069967d71742e2507919', // 申请好的Web端开发者Key,首次调用 load 时必填
version: '2.0', // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
plugins: [
'AMap.ToolBar',
'AMap.Scale',
'AMap.HawkEye',
'AMap.MapType',
'AMap.Geolocation',
'AMap.AutoComplete',
'AMap.PlaceSearch',
'AMap.Geocoder'
] // 需要使用的的插件列表,如比例尺'AMap.Scale'等
})
.then((AMap) => {
const tempCenter = props.defaultPoint[0]
? props.defaultPoint
: [118.784136, 32.041806]
map.value = new AMap.Map('custom-amap', {
// 设置地图容器id
viewMode: '2D', // 是否为3D地图模式
zoom: 12, // 初始化地图级别
showLabel: true, // 是否展示地图文字和 POI 信息。
resizeEnable: true,
center: tempCenter // 初始化地图中心点位置
})
// 如果父组件传入了有效值 回显一个icon
if (props.defaultPoint.length > 0) {
address.value = props.defaultAddress
point.value = props.defaultPoint
addMarker()
}
// 地图点击事件
map.value.on('click', clickMapHandler) // 引入高德地图的空间绑定使用
map.value.addControl(new AMap.Scale())
map.value.addControl(new AMap.ToolBar())
map.value.addControl(new AMap.HawkEye())
map.value.addControl(new AMap.MapType())
map.value.addControl(new AMap.Geolocation()) // 搜索框自动完成类
autoComplete.value = new AMap.AutoComplete({
input: 'keyword' // input 为绑定输入提示功能的input的DOM ID
})
// 构造地点查询类
placeSearch.value = new AMap.PlaceSearch({
map: map.value
})
// 当选中某条搜索记录时触发
autoComplete.value.on('select', selectHandler)
// poi覆盖物点击事件
placeSearch.value.on('markerClick', clickMarkerHandler)
})
.catch((e) => {
console.log(e)
})
} const clickMapHandler = (e) => {
const lng = e.lnglat.lng
const lat = e.lnglat.lat
point.value = [lng, lat]
// 增加点标记
addMarker()
// 获取地址
getAddress()
} // 增加点标记
const addMarker = () => {
// 清除其他icon
if (marker.value) {
marker.value.setMap(null)
marker.value = null
}
// 重新渲染icon
marker.value = new AMap.Marker({
position: point.value, // icon经纬度
offset: new AMap.Pixel(-13, -30), // icon中心点的偏移量
icon: new AMap.Icon({
image:
'//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-default.png',
size: new AMap.Size(30, 40), // 图标大小
imageSize: new AMap.Size(30, 40)
})
})
marker.value.setMap(map.value) // 设置icon
} // 将经纬度转换为地址
const getAddress = () => {
// 获取地址,这里通过高德 SDK 完成。
geocoder.value = new AMap.Geocoder()
// 调用逆解析方法, 个人开发者调用量上限5000(次/日)
geocoder.value.getAddress(point.value, (status, result) => {
if (status === 'complete' && result.info === 'OK') {
if (result && result.regeocode) {
address.value = result.regeocode.formattedAddress
}
}
})
}
// 当选中某条记录时会触发
const selectHandler = (e) => {
placeSearch.value.setCity(e.poi.adcode)
placeSearch.value.search(e.poi.name) // 关键字查询查询
}
// 点击poi覆盖物事件
const clickMarkerHandler = (e) => {
point.value = [e.data.location.lng, e.data.location.lat]
getAddress()
} // 保存当前选择的地址,分发事件
const handelSave = () => {
if (address.value && point.value.length && point.value.length > 0) {
const infoObj = {
address: address.value,
point: point.value
}
tipInput.value = ''
emits('getPosition', infoObj)
} else {
ElMessage.error('请选择地址获取经纬度')
}
}
const cancel = () => {
tipInput.value = ''
emits('getPosition', {})
} onUnmounted(() => {
map.value && map.value.destroy()
})
</script> <style lang="scss" scoped>
.amap-box {
padding: 5px 0 0;
#custom-amap {
width: 700px;
height: 400px;
margin-top: 10px;
border: 1px solid #ccc;
} .input-with {
width: 580px;
z-index: 1;
} .address {
color: #373737;
}
.info-list {
padding: 5px 5px 0;
line-height: 24px;
}
}
</style> <style lang="scss">
.select-map-dialog {
.el-dialog__body {
padding-top: 3px;
padding-bottom: 3px;
}
}
.amap-sug-result {
z-index: 2024;
}
</style>
<template>
  <div class="wrapper">
    <div class="box">
      <div class="title">
        <svg-icon
          class="svg-icon-return-back"
          icon="return-back1"
          @click="returnBack"
        ></svg-icon
        >新建设备实体
      </div>
      <div class="form-box">
        <el-form
          label-position="top"
          :inline="true"
          :model="addDeviceForm"
          ref="addDeviceFormRef"
          :rules="rules"
        >
          <el-form-item label="设备名称" prop="name">
            <el-input
              v-model="addDeviceForm.name"
              placeholder="请输入设备名称"
            />
          </el-form-item>
          <el-form-item label="设备类型:" prop="type">
            <el-select
              v-model="addDeviceForm.type"
              placeholder="全部"
              clearable
            >
              <el-option label="设备类型1" value="1" />
              <el-option label="设备类型2" value="2" />
            </el-select>
          </el-form-item>
          <el-form-item label="设备分组:">
            <el-select
              v-model="addDeviceForm.group"
              placeholder="全部"
              clearable
            >
              <el-option label="设备分组1" value="1" />
              <el-option label="设备分组2" value="2" />
            </el-select>
          </el-form-item>
          <el-form-item label="设备垂直分辨率(px)" prop="verticalResolution">
            <el-input-number
              v-model="addDeviceForm.verticalResolution"
              :min="0"
              :precision="2"
              :step="0.01"
              placeholder="请输入"
              controls-position="right"
            />
          </el-form-item>
          <el-form-item label="设备水平分辨率(px)" prop="levelResolution">
            <el-input-number
              v-model="addDeviceForm.levelResolution"
              :min="0"
              :precision="2"
              :step="0.01"
              placeholder="请输入"
              controls-position="right"
            />
          </el-form-item>
          <el-form-item label="设备安装日期" prop="installDate">
            <el-date-picker
              v-model="addDeviceForm.installDate"
              type="date"
              placeholder="请选择安装日期"
              format="YYYY-MM-DD"
              value-format="YYYY-MM-DD"
              clearable
            />
          </el-form-item>
          <el-form-item label="设备安装位置" prop="indatallAddress">
            <el-input
              @click="showMap"
              :suffix-icon="MapLocation"
              v-model="addDeviceForm.indatallAddress"
            />
          </el-form-item>
          <el-form-item label="设备经度" prop="longitude">
            <el-input-number
              disabled
              :controls="false"
              v-model="addDeviceForm.longitude"
              placeholder="请输入经度"
            />
          </el-form-item>
          <el-form-item label="设备纬度" prop="latitude">
            <el-input-number
              disabled
              :controls="false"
              v-model="addDeviceForm.latitude"
              placeholder="请输入纬度"
            />
          </el-form-item>
          <el-form-item label="设备照片">
            <el-upload
              name="file"
              :show-file-list="false"
              class="avatar-uploader"
              :headers="upload.headerToken"
              :action="upload.imgAction"
              :on-success="handleImgSuccess"
              :before-upload="beforeImgUpload"
            >
              <el-image
                v-if="imageUrl"
                :src="data:imageUrl"
                class="avatar"
                :fit="fit"
              />
              <el-icon v-if="!imageUrl" class="avatar-uploader-icon"
                ><CirclePlus
              /></el-icon>
              <p v-if="!imageUrl" class="tip">请添加jpg/png/gif格式文件</p>
            </el-upload>
          </el-form-item>
        </el-form>
      </div>
    </div>
    <div class="btn-wrapper">
      <span class="btn btn-deault" @click="onSubmit(addDeviceFormRef)">
        提交
      </span>
      <span class="btn btn-plain" @click="onCancel(addDeviceFormRef)">
        取消
      </span>
    </div>
  </div>
  <!-- 地图组件 -->
  <gao-amap
    :isShow="amapVisible"
    :defaultAddress="defaultAddress"
    :defaultPoint="defaultPoint"
    @getPosition="getPosition"
  ></gao-amap>
</template>
<script setup>
import { addLamp } from '@/api/light'
import { ref } from 'vue'
import { ElMessage } from 'element-plus'
import { useStore } from 'vuex'
import { MapLocation } from '@element-plus/icons-vue'
import GaoAmap from '@/components/Amap'
const store = useStore()
const emits = defineEmits(['closeEntityDevicePage'])
const addDeviceFormRef = ref()
const imageUrl = ref('')
const props = defineProps({
  mode: {
    type: String
  }
})
const addDeviceForm = ref({
  name: '',
  type: '',
  group: '',
  verticalResolution: null,
  levelResolution: null,
  indatallAddress: '',
  longitude: null,
  latitude: null,
  installDate: ''
})
const rules = ref({
  name: [
    { required: true, message: '设备名称不能为空', trigger: 'blur' },
    { min: 1, max: 16, message: '设备名称不允许超过16个字符' }
  ],
  type: [{ required: true, message: '设备类型不能为空', trigger: 'change' }],
  installDate: [
    { required: true, message: '设备安装日期不能为空', trigger: 'change' }
  ],
  indatallAddress: [
    { required: true, message: '安装地址不能为空', trigger: 'change' }
  ]
})
const upload = ref({
  headerToken: {
    Authorization: `Bearer ${store.getters.token}`
  },
  imgAction: ''
})
// 自动上传
const beforeImgUpload = (rawFile) => {
  const formatArr = ['image/png', 'image/jpg', 'image/jpeg', 'image/gif']
  const isPic = formatArr.indexOf(rawFile.type.toLowerCase()) !== -1 // 是否为图片
  if (!isPic) {
    ElMessage.error('图片格式错误!')
    return false
  } else if (rawFile.size / 1024 / 1024 > 5) {
    ElMessage.error('图片大小不能超过5MB!')
    return false
  }
  return true
}
const handleImgSuccess = (res) => {
  imageUrl.value = res.data.url
  ElMessage({
    type: 'success',
    message: '上传成功'
  })
}
const onSubmit = async (formEl) => {
  if (!formEl) return
  await formEl.validate(async (valid, fields) => {
    if (valid) {
      const res = await addLamp(addLightForm.value)
      if (res.data.code === 500) {
        ElMessage({
          type: 'warning',
          message: '这个灯杆已存在'
        })
        return
      }
      emits('closeEntityDevicePage')
    } else {
      console.log('error submit!', fields)
    }
  })
}
const onCancel = () => {
  emits('closeEntityDevicePage')
}
const amapVisible = ref(false)
const defaultAddress = ref('')
const defaultPoint = ref([])
const showMap = () => {
  defaultAddress.value = addDeviceForm.value.indatallAddress
  defaultPoint.value = [
    addDeviceForm.value.longitude,
    addDeviceForm.value.latitude
  ]
  amapVisible.value = true
}
const getPosition = (infoObj) => {
  amapVisible.value = false
  if (infoObj.address) {
    addDeviceForm.value.indatallAddress = infoObj.address
    addDeviceForm.value.longitude = infoObj.point[0]
    addDeviceForm.value.latitude = infoObj.point[1]
  }
}
const returnBack = () => {
  emits('closeEntityDevicePage')
}
</script>
<style lang="scss" scoped>
.wrapper {
  width: 100%;
  height: 100%;
}
.box {
  width: 100%;
  height: calc(100% - 60px);
  background: #fff;
  padding: 0 20px;
  .title {
    height: 60px;
    line-height: 60px;
    border-bottom: 1px solid #e9e9e9;
  }
  .form-box {
    height: calc(100% - 120px);
    overflow: auto;
    padding-top: 15px;
  }
}
.btn-wrapper {
  position: fixed;
  right: 0;
  bottom: 0;
  text-align: right;
  width: calc(100% - 240px);
  height: 60px;
  background: #fff;
  padding: 10px 20px;
}
</style>

vue3调用高德地图,实现地址,经纬度填写的更多相关文章

  1. 高德地图模糊搜索地址(elementUI)

    首先引入AMap: 1.在index.html引入AMap <script type="text/javascript" src="http://webapi.am ...

  2. vue项目使用vue-amap调用高德地图api详细步骤

    想要的效果如下 : 高德地图 && 信息窗体 步骤一: 申请高德key 高德开放平台 | 高德地图API (amap.com) (可参考博客:   [996]如何申请高德地图用户Key ...

  3. 在uni-app中调用高德地图去导航

    1.判断一下是不是在微信环境 2.微信环境调用微信自带的地图导航 3.h5环境跳转去高德地图 guide() { let self = this; console.log("self.lat ...

  4. vue调用高德地图:vue-amap

    前言:之前没有接触过页面调用地图的项目,某次面试,老板要求我用vue-amap调用高德地图,回家以后,我去网上查了一些案例和教程,看似很简单的引入调用,我却整整弄了一宿,还没弄出来!!!百般无奈之下, ...

  5. java调用高德地图api实现通过ip定位访问者的城市

    所需东西:高德地图的key 注意:这个key是 web服务的key  和js的key不是一个key(若没有则自行创建,创建教程在文末) 高德地图的api文档:https://lbs.amap.com/ ...

  6. vue 调用高德地图

    一. vue-amap,一个基于 Vue 2.x 和高德地图的地图组件 https://elemefe.github.io/vue-amap/#/ 这个就不细说了,按照其文档,就能够安装下来. 二. ...

  7. 关于Android studio调用高德地图的简单流程和要点

    一,账号与Key的申请 注册成为高德开发者需要分三步: 第一步,注册高德开发者:第二步,去控制台创建应用:第三步,获取Key. 前2步都比较简单,这里说下第三步. 获取Key 1.进入控制台,创建一个 ...

  8. uni-app中调用高德地图去设置点和轨迹

    盒子部分 <view style="width: 100%; height: 100%" id="busContainer"> </view& ...

  9. VUE 高德地图选取地址组件开发

    高德地图文档地址 http://lbs.amap.com/api/lightmap/guide/picker/ 结合步骤: 1.通过iframe内嵌引入高德地图组件 key就选你自己申请的key &l ...

  10. andriod 调用高德地图

    Android Studio 配置工程             最后更新时间: 2017年08月29日 来自:http://lbs.amap.com/api/android-sdk/guide/cre ...

随机推荐

  1. 使用动画曲线编辑器打造炫酷的3D可视化ACE

    前言 在制作3D可视化看板时,除了精细的模型结构外,炫酷的动画效果也是必不可少的.无论是复杂的还是简单的动画效果,要实现100%的自然平滑都是具有挑战性的工作.这涉及到物理引擎的计算和对动画效果的数学 ...

  2. 安卓之DocumentsProvider应用场景以及优劣分析

    文章摘要 本文深入探讨了安卓DocumentsProvider的应用场景,分析了其优势与不足,并提供了简单的代码实现.DocumentsProvider是安卓系统中用于文件存储与访问的关键组件,为应用 ...

  3. python 获取android 应用使用情况

    python 获取android 应用使用情况 本文主要讲述python 脚本获取android 应用使用情况. 主要思路:使用adb 获取当前activity ,1s 一次输出. 主要涉及知识点: ...

  4. Javascript实现Canvas绘图 —— 2D绘图之填充、描边及绘制矩形

    Canvas绘图的实现: <canvas>元素负责在页面中设定一个区域,通过JS动态地在这个区域中绘制图形. IE9+.Firefox1.5+.Safari2+.Opera9+.Chrom ...

  5. vscode快速配置汇编环境

    微机原理的课程需要,简单快速记录环境的搭建 找到并安装插件masm. MASM/TASM的汇编工具默认是tasm这样就无法在vscode终端进行debug,打开插件设置如下修改: 测试代码实现小写字母 ...

  6. .net Core实战简单文件服务器

    首先新建一个ASP.NET Core 项目,选中空的模板,如下图所示 在NuGet包中添加Microsoft.AspNetCore.StaticFiles 添加好以后我们在Startup.cs中添加对 ...

  7. 下载安装Android Studio

    1,安装java的jdk 2,下载安装Dart 3,下载安装  Android Studio 建议这个安装在C盘,以防后期出现各种问题 在plugins中 (1)下载dart插件 (2)下载flutt ...

  8. 十分钟从入门到精通(上)——OBS权限配置

    [摘要]作为公有云的数据底座,大量的应用场景产生的数据都会存储到OBS对象存储服务中,如直播.电商.大数据可视化.机器学习.物联网等.作为公有云的海量存储基础服务, OBS提供了灵活的权限配置功能,解 ...

  9. 7000+字图文并茂解带你深入理解java锁升级的每个细节

    摘要:对于java锁升级,很多人都停留在比较浅层的表面理解,这篇7000+字和图解带你深入理解锁升级的每个细节. 本文分享自华为云社区<对java锁升级,你是否还停留在表面的理解?7000+字和 ...

  10. FusionInsight怎么帮「宇宙行」建一个好的「云数据平台」?

    摘要:基于数据湖架构,应用效率得以极大提升.经过几年发展,当前集群规模已经达到1000多节点,数据量几十PB,日均处理作业数大概是10万,赋能于180多个总行应用和境内外41家分行及子公司. 本文分享 ...