使用百度地图bmap
去年就应该写的一篇博客,还好有素材,现在直接用了
我用的是百度地图的bmap
网址是:https://dafrok.github.io/vue-baidu-map/#/zh/index
啥话不说,上代码
安装:
$ npm install vue-baidu-map --save
这里我是全局引用的,直接在vue项目中的main.js中
import BaiduMap from 'vue-baidu-map'
// 引入百度地图
Vue.use(BaiduMap, {
// ak 是在百度地图开发者平台申请的密钥 详见 http://lbsyun.baidu.com/apiconsole/key */
ak: 'XGePQBHjcW7GXyvx51BUGxGHAgGAGCNu'
// 这个ak需要自己去百度地图上去申请,申请步骤可自行百度,这边我就不去详细介绍了
})
在页面中使用,这边我是需要做一个地区的三级联动
我的页面代码有点长
我只弄我需要的代码
<template>
<div>
<!-- 面包屑 -->
<el-breadcrumb separator="/">
<el-breadcrumb-item>基础设置</el-breadcrumb-item>
<el-breadcrumb-item class="breadcrumb_tow">提卸货单位</el-breadcrumb-item>
</el-breadcrumb>
<!-- /面包屑 -->
<!-- 卡片区域 -->
<div style="height:100%">
<!-- 添加单位对话框 -->
<el-dialog
:before-close= "cancelAdd"
title="添加联系单位"
:visible.sync="addUnitDialogVisible"
width="55%"
@close="addUnitDialogClosed">
<el-tabs v-model="activeName" @tab-click="handleClick">
<!-- ***************************************单位信息************************************* -->
<el-tab-pane label="单位信息" name="first">
<!-- 内容主体 -->
<el-form
:model="goodsdata"
:rules="goodsdataRules"
ref="addGoodsdataRef"
label-width="100px">
<el-form-item
label="单位类型"
prop="unitType"
>
<el-select v-model="goodsdata.unitType" placeholder="请输入单位信息" style="width:690px">
<el-option label="提货单位" value="0"></el-option>
<el-option label="卸货单位" value="1"></el-option>
</el-select>
</el-form-item>
<el-form-item
label="单位名称"
prop="unitName">
<el-input
placeholder="请输入单位名称"
v-model="goodsdata.unitName">
</el-input>
</el-form-item>
<el-form-item
label="单位证件号"
prop="unitCode">
<el-input
placeholder="请输入单位信息"
v-model="goodsdata.unitCode">
</el-input>
</el-form-item>
<el-form-item
label="单位地址"
prop="address">
<!-- 级联选择器 -->
<el-cascader
style="width:690px"
v-model="goodsdata.address"
:options="citydata"
:props="cityProps"
clearable
placeholder="请输入单位地址">
</el-cascader>
</el-form-item>
</el-form>
<!-- /内容主体 -->
</el-tab-pane>
<!-- ********************************************联系人*************************************** -->
<el-tab-pane
label="联系人"
name="second"
>
<!-- 添加联系人 -->
<el-form
:rules="contactRules"
label-width="100px"
:inline="true"
:model="contact"
ref="contactRef">
<el-form-item
prop="name"
label="人员姓名">
<el-input
v-model="contact.name"
placeholder="人员姓名"></el-input>
</el-form-item>
<el-form-item
prop="phone"
label="联系电话">
<el-input
v-model="contact.phone"
placeholder="联系电话"></el-input>
</el-form-item>
<el-button
type="warning"
style="marginLeft:30px"
@click="addcontact">
添加联系人
</el-button>
</el-form>
<!-- /添加联系人 -->
<!-- 添加联系人生成的列表 -->
<el-table
:data="goodsdata.contactsList"
style="width: 100%"
height="500px"
>
<el-table-column
prop="contactsUse"
label="是否默认"
width="200">
<span slot-scope="{row}">{{row.contactsUse?'是':'否'}}</span>
</el-table-column>
<el-table-column
prop="name"
label="人员姓名"
width="200">
</el-table-column>
<el-table-column
prop="phone"
label="联系电话"
width="200">
</el-table-column>
<el-table-column
label="操作"
width="200"
prop="contactsUse"
>
<template slot-scope="scope">
<template v-if="!scope.row.contactsUse">
<el-tooltip
class="item"
effect="dark"
content="默认"
placement="top"
:open-delay="500">
<el-button
size="mini"
type="warning"
icon="el-icon-s-custom"
@click= "defaultcontact(scope.row.id)"
></el-button>
</el-tooltip>
<el-tooltip
class="item"
effect="dark"
content="删除"
placement="top"
:open-delay="500">
<el-button
class="delete"
size="mini"
type="danger"
icon="el-icon-delete"
@click="removeContacts(scope.row.id)"
>删除</el-button>
</el-tooltip>
</template>
</template>
</el-table-column>
</el-table>
<!-- /添加联系人生成的列表 -->
</el-tab-pane>
<!-- ********************************************联系地址*************************************** -->
<el-tab-pane
label="联系地址"
name="third">
<!-- 底部区域 -->
<span
style="width:100%;height:50px">
<el-button
type="primary"
class="backinfo_button"
@click="cancelAdd">
取 消
</el-button>
<el-button
type="warning"
@click="addUnitInformation">
保 存
</el-button>
</span>
<!-- /底部区域 -->
<!-- 添加联系地址 -->
<el-form
ref= "addressRulesRef"
:rules= "addressRules"
label-width="150px"
:inline="true"
:model="address">
<el-form-item
label="所属地区"
prop="region"
>
<!-- 级联选择器 -->
<el-cascader
style="width:600px"
v-model="address.region"
:options="citydata"
:props="cityProps"
clearable
placeholder="请选择所属地区"
@change="enterRegion">
</el-cascader>
</el-form-item>
<el-form-item
label="地址"
prop="addressName">
<el-input
clearable
style="width:600px"
placeholder="请输入地址"
@change="enterAddress"
v-model="address.addressName">
</el-input>
</el-form-item>
<el-form-item
label="详细地址简称"
prop="addressDetail">
<el-input
placeholder="请输入详细地址简称"
v-model="address.addressDetail">
</el-input>
</el-form-item>
<el-button
type="warning"
style="marginLeft:250px"
@click="addAddress"> 添加联系地址 </el-button> </el-form> <!-- /添加联系地址 --> <!-- 百度地图 --> <div style="width:100%;height:400px" >
<baidu-map
class="map"
:center="center"
:mapClick="false"
:zoom="zoom"
:scroll-wheel-zoom="true"
@click="getClickInfo"
@ready="onBaiduMap"
@moving="syncCenterAndZoom"
@moveend="syncCenterAndZoom"
@zoomend="syncCenterAndZoom" > <!-- 地图视图 --> <bm-view style="width:100%;height:100%"></bm-view>
<!-- 缩放组件 -->
<bm-navigation anchor="BMAP_ANCHOR_TOP_RIGHT"></bm-navigation>
<!-- 覆盖物--点标记 -->
<bm-marker :position="{lng: center.lng, lat: center.lat}"></bm-marker>
<!-- 自动填充组件--- 可配合input框使用 -->
<bm-control offset="{width:'10px';height:'10px'}">
<bm-auto-complete v-model="keyword" :sugStyle="{zIndex: 999}">
<el-input v-model="keyword" type="text" placeholder="请输入关键字" clearable>
<!-- <i></i> -->
</el-input>
</bm-auto-complete>
</bm-control>
<!-- 定位组件 -->
<bm-geolocation anchor="BMAP_ANCHOR_BOTTOM_RIGHT" :showAddressBar="true" :autoLocation="true"></bm-geolocation>
<!-- 地区检索组件 -->
<bm-local-search :keyword="keyword" :auto-viewport="true" :panel="false" @searchcomplete="searchcomplete"></bm-local-search>
</baidu-map>
</div>
<!-- /百度地图 -->
<!-- 添加联系地址所生成得列表 -->
<el-table
:data="goodsdata.addressList"
style="width: 100%"
height="300px"
>
<el-table-column
prop="addressUse"
label="是否默认"
width="115">
<span slot-scope="{row}">{{row.addressUse?'是':'否'}}</span>
</el-table-column>
<el-table-column
prop="region"
label="所属地区"
width="115">
</el-table-column>
<el-table-column
prop="addressName"
label="联系地址"
width="115">
</el-table-column>
<el-table-column
prop="addressDetail"
label="地址简称"
width="115">
</el-table-column>
<el-table-column
prop="longitude"
label="经度"
width="115">
</el-table-column>
<el-table-column
prop="latitude"
label="纬度"
width="115">
</el-table-column>
<el-table-column
label="操作"
width="115"
>
<template slot-scope="scope">
<el-button
class="delete"
size="mini"
type="danger"
icon="el-icon-delete"
@click="removeAddress(scope.row.id)"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- /添加联系地址所生成得列表-->
</el-tab-pane>
</el-tabs>
</el-dialog>
<!--/ 添加单位对话框 -->
</div>
<!-- /卡片区域 -->
</div>
</template>
<script>
import { mapActions, mapState } from 'vuex'
import { CONST_HEADER } from '@api/axios/default'
// 导入省市区js数据
import citydata from '@utils/citydata.js'
export default {
data () {
// 自定义手机号校验规则
var checkPhone = (rule, value, callback) => {
if (!value) {
return callback(new Error("手机号不能为空"));
} else {
const reg = /^1[3|4|5|7|8][0-9]\d{8}$/;
if (reg.test(value)) {
callback();
} else {
return callback(new Error("请输入正确的手机号"));
}
}
};
return {
// 地图组件是否就绪
map: null,
Bmap: null,
center: { // 中心点
lng: 116.404,
lat: 39.915
},
zoom: 12, // 地图缩放比例
// 地区检索信息
keyword: '', // 地图组件里的变量、关键字
choosedLocation: { // 省市区数据回显
province: '',
city: '',
district: '',
addr: ''
},
goodsdata: {
// 添加单位数据
unitType: null,
unitName: '',
unitCode: '',
address: '',
// 添加联系人信息列表
contactsList: [],
// 添加联系地址信息列表
addressList: []
},
// 添加联系人数据 联系人信息
contact: {
id: +new Date(),
name: '',
phone: '',
contactsUse: false
},
// 添加联系地址的数据 地址信息
address: {
id: +new Date(),
region: [],
addressName: '',
addressDetail: '',
addressUse: false,
longitude: 0,
latitude: 0
},
// table栏切换(默认在第二个)
activeName: 'first',
// 添加对话框的显示跟隐藏
addUnitDialogVisible: false,
// 添加单位名称的验证规则
goodsdataRules: {
unitType: [
{ required: true, message: '不能为空' }
],
unitName: [
{ required: true, message: '请输入单位名称', trigger: 'blur' },
{ min: 2, max: 50, message: '(2-50位)可输入中文、英文、()、数字,但必须包含中文单位证件号:', trigger: 'blur' }
],
unitCode: [
{ required: true, message: '不能为空', trigger: 'blur' }
],
address: [
{ required: true, message: '不能为空', trigger: 'blur' }
]
},
// 添加联系人验证规则
contactRules: {
name: [
{ required: true, message: '不能为空', trigger: 'blur' }
],
phone: [
{ required: true, validator: checkPhone, trigger: ["blur", "change"] }
]
},
// 地址得验证规则(不能为空)
addressRules: {
region: [
{ required: true, message: '不能为空', trigger: 'blur' }
],
addressName: [
{ required: true, message: '不能为空', trigger: 'blur' }
],
addressDetail: [
{ required: true, message: '不能为空', trigger: 'blur' }
]
},
}
},
created () {
// 获取角色
this.userlist = JSON.parse(sessionStorage.getItem("userlist"))
// 权限分配
this.power()
// 请求单位列表数据
this.getUnitList()
},
computed: {
...mapState('setting', ['goodsUnitList', 'pageParams']),
},
mounted () {
},
methods: {
// 添加联系地址到列表中
addAddress () {
// 利用验证规则进行添加
this.$refs.addressRulesRef.validate(async valid => {
if (!valid) return
// 进行深克隆改变栈的地址
// const v = await Object.assign({}, this.address)
const v = JSON.parse(JSON.stringify(this.address))
v.id = +new Date()
// 经纬度
// v.longitude = 52.23
// v.latitude = 852.23
// 设置默认联系人
if (!this.goodsdata.addressList.length) {
v.addressUse = true
}
this.goodsdata.addressList.unshift(v)
// 重置数据
this.$refs.addressRulesRef.resetFields()
})
},
// 添加单位数据到列表中
async addUnitInformation () {
this.loading = true
this.goodsdata.unitType = parseInt(this.goodsdata.unitType)
// 剔除id元素
this.goodsdata.contactsList.forEach(v => {
delete v.id
})
this.goodsdata.addressList.forEach(v => {
delete v.id
if(Object.prototype.toString.call(v.region)==='[object Array]'){ // 判断是否为数组的方法
v.region = v.region.join('/')
}
})
// console.log(this.goodsdata.address)
if(Object.prototype.toString.call(this.goodsdata.address)==='[object Array]'){
this.goodsdata.address = this.goodsdata.address.join('/')
}
// 发送请求 保存单位数据信息
if(this.userlist.userType === 20) {
const { code, data, msg} = await this.addGoodsUnitListAdmin(this.goodsdata)
this.loading = false
if (code !== 200) {
return this.$message.error(msg)
}
} else if(this.userlist.userType === 15) {
const { code, data, msg} = await this.addGoodsUnitList(this.goodsdata)
this.loading = false
if (code !== 200) {
return this.$message.error(msg)
}
}
this.cancelAdd()
},
cancelAdd () {
// 关闭添加单位弹窗
this.addUnitDialogVisible = false
// 重置选项卡
this.activeName = 'first'
// 清除添加联系人跟联系地址的数据
this.goodsdata.contactsList = []
this.goodsdata.addressList = []
// 重置表单
this.$refs.addGoodsdataRef.resetFields()
},
// 点击编辑按钮,触发该事件 修改当前联系单位并弹出对话框
async editUnit (unitId) {
// 打开编辑弹窗
this.editUnitDialogVisible = true
this.loading = true
if(this.userlist.userType === 20) {
const { code, data, msg} = await this.getGoodsUnitDetailListAdmin({ unitId })
this.loading = false
// 把数据存入表单中进行显示
this.goodsdata = data
// 将状态转化为字符串
this.goodsdata.unitType = data.unitType.toString()
}else if(this.userlist.userType === 15) {
const { code, data, msg} = await this.getGoodsUnitDetailList({ unitId })
this.loading = false
// 把数据存入表单中进行显示
this.goodsdata = data
// 将状态转化为字符串
this.goodsdata.unitType = data.unitType.toString()
}
this.goodsdata.address = this.goodsdata.address.split('/')
// 给联系人和联系地址设置id
this.goodsdata.contactsList.forEach(v=>{
v.id= +new Date
v.contactsUse = v.contactsUse
})
this.goodsdata.addressList.forEach(v=>{
v.id= +new Date
v.addressUse = v.addressUse
})
// console.log(1111,this.goodsdata)
},
// 监听修改单位对话框的监听事件,作用是关闭页面时表单会重置当前页面
editUnitDialogClosed () {
this.$refs.editGoodsdataRef.resetFields()
},
// 发送请求
// 获取列表数据,渲染页面
async getUnitList () {
this.loading = true
// 判断角色
if(this.userlist.userType === 20) {
const { code, data, msg } = await this.getGoodsUnitListAdmin(this.pageParams)
this.loading = false
if (code !== 200) {
return this.$message.error('获取单位列表失败')
} else {
this.$message.success(msg)
}
} else if(this.userlist.userType === 15){
const { code, data, msg } = await this.getGoodsUnitList(this.pageParams)
this.loading = false
if (code !== 200) {
return this.$message.error('获取单位列表失败')
} else {
this.$message.success(msg)
}
}
},
// 修改每页显示多少条
handleSizeChange (newVal) {
// newVal是最新的pagesize值,重新赋值给pagesize
this.pageParams.pageSize = newVal
// 刷新页面
this.getUnitList()
},
// pageNum发生变化触发的函数
handleCurrentChange (newVal) {
// newVal是最新的pagenum值,重新赋值给pagenum
this.pageParams.pageNum = newVal
this.getUnitList()
},
// 联系地址---所属地区的change事件
enterRegion(event) {
this.keyword = event.join('/')
this.address.addressName = this.keyword
},
// 联系地址---地址的change事件
enterAddress(event) {
this.goodsdata.addressList.find(v=>v).addressName = event
},
// 地图的点击事件
getClickInfo (e) {
// 调整地图中心位置
this.center.lng = e.point.lng
this.center.lat = e.point.lat
// 此时已经可以获取到BMap类
if (this.BMap) {
const that = this
// Geocoder() 类进行地址解析
// 创建地址解析器的实例
const geoCoder = new this.BMap.Geocoder()
// getLocation() 类--利用坐标获取地址的详细信息
// getPoint() 类--获取位置对应的坐标
geoCoder.getLocation(e.point, (res) => {
console.log('获取经纬度', e.point, '获取详细地址', res)
this.address.addressName = res.address
this.address.longitude = e.point.lng // 经度
this.address.latitude = e.point.lat // 纬度
const addrComponent = res.addressComponents
const surroundingPois = res.surroundingPois
const province = addrComponent.province
const city = addrComponent.city
const district = addrComponent.district
let addr = addrComponent.street
if(res.addressComponents.province === res.addressComponents.city) {
this.address.region = [res.addressComponents.province, res.addressComponents.district]
}else{
this.address.region = [res.addressComponents.province, res.addressComponents.city, res.addressComponents.district]
}
if (surroundingPois.length > 0 && surroundingPois[0].title) {
if (addr) {
addr += `-${surroundingPois[0].title}`
} else {
addr += `${surroundingPois[0].title}`
}
} else {
addr += addrComponent.streetNumber
}
that.choosedLocation = { province, city, district, addr }
})
}
},
onBaiduMap (e) {
console.log('返回BMap类和map实例', e)
this.BMap = e.BMap
this.map = e.map
if (this.BMap) {
// 获取定位地址信息并赋值给声明变量
// Geolocation 对象的 getCurrentPosition()、watchPosition()、clearWatch() 方法详解 :https://blog.csdn.net/zyz00000000/article/details/82774543
const geolocation = new this.BMap.Geolocation()
// 通过 getCurrentPosition() 方法:获取当前的位置信息
geolocation.getCurrentPosition(res => {
const that = this
console.log('返回详细地址和经纬度', res)
const { lng, lat } = res.point
// eslint-disable-next-line camelcase
const { province, city, district, street, street_number } = res.address
that.center = { lng, lat }
that.address.longitude = that.center.lng
that.address.latitude = that.center.lng
that.choosedLocation = { province, city, district, addr: street + street_number }
})
}
},
syncCenterAndZoom (e) {
// 返回地图当前的缩放级别
this.zoom = e.target.getZoom()
},
removeAdd(e) {
// console.log(e.point,123456)
console.log('aeirfbcd;oubaewfkldscubfusbjkdamn z')
},
searchcomplete (e) {
this.$nextTick(() => {
// if (e && e.Hr) {
// console.log(e.Hr[0],123123123)
// this.center = e.Hr[0].pointN; // 这里获取了检索的位置并跳转
// this.map.clearOverlays(); // 这里进行清除所有的点
// this.getClickInfo(); // 这里的init就是接下来的业务操作。
// // this.onBaiduMap()
// }
})
}
},
destroyed () {
window.removeEventListener('resize', ()=>{
this.tableHeight = window.innerHeight - 260
})
}
}
</script>
<style lang="less" scoped>
.el-input__inner{
width: 500px !important;
}
.map{
width: 100%;
height: 400px;
}
div.BMap_pop{
display: none !important;
}
.BMap_shadow img{
display: none !important;
}
// .BMap_Marker{
// display: none !important;
// }
// .BMap_noprint{
// display: none !important;
// }
/deep/ .BMap_pop{
display: none !important;
}
/deep/ .BMap_shadow img{
display: none !important;
}
</style>
代码中已经详细介绍了用法,以及代码,主要是vue项目中引用百度地图特别方便