vue集成百度地图实现搜索功能
效果:
1.在index.html中
引入百度
<script type="text/javascript" src="http://api.map.baidu.com/api?v=3.0&ak=xxxx密钥"></script>
修改为
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= htmlWebpackPlugin.options.title %></title>
<script type="text/javascript" src="http://api.map.baidu.com/api?v=3.0&ak=xx你的密钥"></script>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
2. 新增地图选址组件test.vue
<template>
<el-dialog title="请选择地址" :visible.sync="open" width="900px" append-to-body>
<el-form label-width="80px">
<el-row>
<el-col :span="10">
<el-form-item label="搜索地址">
<el-input type="text" id="searchAddress" v-model="searchAddress" placeholder="请输入地址"></el-input>
</el-form-item>
</el-col>
<el-col :span="14">
<el-form-item label="当前地址">
<el-input v-model="addressInfo.address" placeholder="请输入内容">
<template slot="prepend">
{{addressInfo.province}}{{addressInfo.city}}{{addressInfo.district}}
</template>
</el-input>
</el-form-item>
</el-col>
</el-row>
</el-form>
<!-- 百度地图 -->
<div id="map-container" style="width: 100%; height: 400px;"></div>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="confirm">确定</el-button>
<el-button @click="cancel">取消</el-button>
</div>
</el-dialog>
</template>
<script>
export default {
data() {
return {
// 搜索地址
searchAddress: "",
// 地址信息
addressInfo: {
// 经度
longitude: "",
// 纬度
latitude: "",
// 省
province: "",
// 市
city: "",
// 区
district: "",
// 详细地址
address: ""
},
open: false,
}
},
methods: {
// 初始化百度地图
initBaiduMap() {
let that = this;
this.$nextTick(function () {
/* 初始化地图 start */
var map = new BMap.Map("map-container") // 创建地图实例
var point = new BMap.Point(113.72649505404026, 34.62123727714748); // 设置中心点坐标
map.centerAndZoom(point, 16); // 地图初始化,同时设置地图展示级别
map.enableScrollWheelZoom(true); //开启鼠标滚轮缩放
var marker = new BMap.Marker(point); // 创建标注
map.addOverlay(marker); // 将标注添加到地图中
/* 初始化地图 end */
/** 点击地图创建坐标事件Start */
// 添加地图点击事件
map.addEventListener("click", function (e) {
var click = e.point; // 点击的坐标
map.clearOverlays(); // 移除地图上的标注
var marker = new BMap.Marker(click); // 创建标注
map.addOverlay(marker); // 将标注添加到地图中
})
/** 点击地图创建坐标事件End */
/** 搜索地址Start */
// 建立一个自动完成的对象
var ac = new BMap.Autocomplete({
input: "searchAddress",
location: map,
});
// 鼠标点击下拉列表后的事件
ac.addEventListener("onconfirm", function (e) {
map.clearOverlays();
var local = new BMap.LocalSearch(map, {
// 智能搜索
onSearchComplete: function (res) {
let poi = res.getPoi(0); // 获取第一个智能搜索的结果
var searchpt = poi.point; // 获取坐标
map.centerAndZoom(searchpt, 16);
map.addOverlay(new BMap.Marker(searchpt));
that.geocAddress(searchpt);
}
});
// 搜索词
var searchValue = e.item.value;
local.search(
searchValue.province +
searchValue.city +
searchValue.district +
searchValue.street +
searchValue.business
)
});
/** 搜索地址End */
})
},
// 逆向解析地址
geocAddress(point) {
let that = this;
var geoc = new BMap.Geocoder();
geoc.getLocation(point, function (geocInfo) {
// 设置基本信息
var addressInfo = geocInfo.addressComponents;
that.addressInfo.longitude = point.lng;
that.addressInfo.latitude = point.lat;
that.addressInfo.province = addressInfo.province;
that.addressInfo.city = addressInfo.city;
that.addressInfo.district = addressInfo.district;
let address = addressInfo.street + addressInfo.streetNumber;
if (geocInfo.surroundingPois.length > 0) {
address = address + geocInfo.surroundingPois[0].title;
}
that.addressInfo.address = address;
});
},
/** 打开地图选择 */
show(){
this.open = true;
this.initBaiduMap();
},
/** 确认选择 */
confirm() {
this.$emit("confirmMapAddress", this.addressInfo);
this.open = false;
},
cancel() {
this.open = false;
}
},
}
</script>
<style lang="scss">
// 防止地图自动完成的对象被遮挡
.tangram-suggestion {
z-index: 9999;
}
</style>
3.主调用的vue
<template>
<div class="app-container">
<el-row>
<el-col :span="12">
<el-form ref="addressInfo" :model="addressInfo" :rules="rules" label-width="100px">
<el-form-item label="小区地址" prop="address">
<el-input placeholder="请选择地址" v-model="addressInfo.address" disabled>
<template slot="prepend">{{addressInfo.province}}{{addressInfo.city}}{{addressInfo.district}}</template>
<el-button slot="append" icon="el-icon-map" @click="showMap" type="primary">选择地址</el-button>
</el-input>
</el-form-item>
<el-row>
</el-row>
</el-form>
</el-col>
</el-row>
<!-- 百度地图位置选择 -->
<BaiduMapSelect ref="bmapAddressSelect" @confirmMapAddress="confirmMapAddress"></BaiduMapSelect>
</div>
</template>
<script>
import BMapAddressSelect from "@/views/front/test";
import Vue from 'vue';
Vue.component('BaiduMapSelect', BMapAddressSelect);
export default {
data() {
return {
// 位置信息
addressInfo: {},
// 表单校验
rules: {},
};
},
components: {
BMapAddressSelect
},
methods: {
/** 显示地图 */
showMap() {
this.$refs.bmapAddressSelect.show();
},
/** 确认地图地址 */
confirmMapAddress(addressInfo) {
this.addressInfo = addressInfo;
},
},
};
</script>
注意点
1.引入test.vue import BMapAddressSelect from “@/views/front/test”;
2.引入vue
3.地址转经纬度 ----》用于打开地图的中心位置选择
地址转经纬度
https://lbs.baidu.com/faq/api?title=webapi/guide/webservice-geocoding-base
4.地图详细大小范围设置,在test.vue的方法中, map.centerAndZoom(point, 16);
测试
address.vue
<template>
<div class="main-content">
<div style="width: 70%; background-color: white; margin: 30px auto; border-radius: 20px">
<div style="padding-bottom: 10px">
<div style="display: flex; font-size: 18px; color: #000000FF; line-height: 80px; border-bottom: #cccccc 1px solid;">
<div style="flex: 3; margin-left: 20px">我的地址</div>
<div style="flex: 1; text-align: right; padding-right: 20px">
<el-button type="warning" round @click="addAddress">添加收货地址</el-button>
</div>
</div>
<div style="margin: 20px 0; padding: 0 50px">
<div class="table">
<el-table :data="addressData" strip>
<el-table-column prop="username" label="收货人" width="350px"></el-table-column>
<el-table-column prop="useraddress" label="收货地址"></el-table-column>
<el-table-column prop="phone" label="联系电话"></el-table-column>
<el-table-column label="操作" align="center" width="180">
<template v-slot="scope">
<el-button size="mini" type="primary" plain @click="editAddress(scope.row)">编辑</el-button>
<el-button size="mini" type="danger" plain @click="del(scope.row.id)">删除</el-button>
</template>
</el-table-column>
</el-table>
<div class="pagination" style="margin-top: 20px">
<el-pagination
background
@current-change="handleCurrentChange"
:current-page="pageNum"
:page-sizes="[5, 10, 20]"
:page-size="pageSize"
layout="total, prev, pager, next"
:total="total">
</el-pagination>
</div>
</div>
</div>
</div>
</div>
<el-dialog title="地址信息" :visible.sync="formVisible" width="40%" :close-on-click-modal="false" destroy-on-close>
<el-form label-width="100px" style="padding-right: 50px" :model="form" :rules="rules" ref="formRef">
<el-form-item prop="username" label="收货人">
<el-input v-model="form.username" autocomplete="off"></el-input>
</el-form-item>
<el-form-item prop="useraddress" label="收货地址">
<el-input v-model="form.useraddress" autocomplete="off"></el-input>
<el-button size="mini" type="danger" plain @click="serdizhi">定位位置</el-button>
</el-form-item>
<el-form-item prop="phone" label="联系电话">
<el-input v-model="form.phone" autocomplete="off"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="formVisible = false">取 消</el-button>
<el-button type="primary" @click="save">确 定</el-button>
</div>
</el-dialog>
<el-dialog title="请选择地址" :visible.sync="fromVisible2" width="40%" :close-on-click-modal="false" destroy-on-close>
<el-row>
<el-col :span="12">
<el-form ref="addressInfo" :model="addressInfo" :rules="rules" label-width="100px">
<el-form-item label="当前位置" prop="address">
<el-input placeholder="请选择地址" v-model="addressInfo.address" disabled>
<template slot="prepend">{{addressInfo.province}}{{addressInfo.city}}{{addressInfo.district}}</template>
<el-button slot="append" icon="el-icon-map" @click="showMap" type="primary">选择地址</el-button>
</el-input>
</el-form-item>
</el-form>
</el-col>
</el-row>
<BaiduMapSelect ref="bmapAddressSelect" @confirmMapAddress="confirmMapAddress"></BaiduMapSelect>
<div slot="footer" class="dialog-footer">
<el-button @click="fromVisible2 = false">取 消</el-button>
<el-button type="primary" @click="savedizhi">确 定</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import BMapAddressSelect from "@/views/utils/BaiduUtils.vue";
import Vue from 'vue';
Vue.component('BaiduMapSelect', BMapAddressSelect);
export default {
data() {
return {
user: JSON.parse(localStorage.getItem('xm-user') || '{}'),
addressData: [],
pageNum: 1, // 当前的页码
pageSize: 10, // 每页显示的个数
total: 0,
formVisible: false,
fromVisible2:false,
form: {},
rules: {
username: [
{required: true, message: '请输入收货人', trigger: 'blur'},
],
useraddress: [
{required: true, message: '请输入收货地址', trigger: 'blur'},
],
phone: [
{required: true, message: '请输入联系电话', trigger: 'blur'},
],
},
addressInfo: {},
}
},
mounted() {
this.loadAddress(1)
},
components: {
BMapAddressSelect
},
// methods:本页面所有的点击事件或者其他函数定义区
methods: {
addAddress() {
this.form = {}
this.formVisible = true
},
editAddress(row) {
this.form = JSON.parse(JSON.stringify(row))
this.formVisible = true
},
save() { // 保存按钮触发的逻辑 它会触发新增或者更新
this.$refs.formRef.validate((valid) => {
if (valid) {
this.form.userId = this.user.id
this.$request({
url: this.form.id ? '/address/update' : '/address/add',
method: this.form.id ? 'PUT' : 'POST',
data: this.form
}).then(res => {
if (res.code === '200') { // 表示成功保存
this.$message.success('保存成功')
this.loadAddress(1)
this.formVisible = false
} else {
this.$message.error(res.msg) // 弹出错误的信息
}
})
}
})
},
loadAddress(pageNum) {
if (pageNum) this.pageNum = pageNum
this.$request.get('/address/selectPage', {
params: {
pageNum: this.pageNum,
pageSize: this.pageSize,
}
}).then(res => {
if (res.code === '200') {
this.addressData = res.data?.list
this.total = res.data?.total
} else {
this.$message.error(res.msg)
}
})
},
navTo(url) {
location.href = url
},
del(id) {
this.$request.delete('/address/delete/' + id).then(res => {
if (res.code === '200') {
this.$message.success('删除成功')
this.loadAddress(1)
} else {
this.$message.error(res.msg)
}
})
},
handleCurrentChange(pageNum) {
this.loadAddress(pageNum)
},
/** 显示地图 */
showMap() {
this.$refs.bmapAddressSelect.show();
},
/** 确认地图地址 */
confirmMapAddress(addressInfo) {
this.addressInfo = addressInfo;
},
savedizhi() {
// Check if addressInfo is not empty
if (Object.keys(this.addressInfo).length !== 0) {
// Update useraddress with the selected address data
this.form.useraddress = `${this.addressInfo.province}${this.addressInfo.city}${this.addressInfo.district}${this.addressInfo.address}`;
// Close the second dialog
this.fromVisible2 = false;
this.$message.success("地址定位成功!");
}
},
serdizhi(){
this.fromVisible2 = true
}
}
}
</script>
效果展示图:
如有侵权,请告知。