首页 前端知识 vue集成百度地图实现搜索功能

vue集成百度地图实现搜索功能

2024-06-05 13:06:38 前端知识 前端哥 873 479 我要收藏

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>

效果展示图:
请添加图片描述

如有侵权,请告知。

转载请注明出处或者链接地址:https://www.qianduange.cn//article/10838.html
评论
发布的文章
大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!