vue版本--腾讯地图demo,可搜索关键字和经纬度,显示地图和搜索结果列表

22 篇文章 0 订阅

腾讯地图demo,改正确的key即可用

<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8">
  <title>腾讯地图</title>
  <meta content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no"
    name="viewport">
</head>
<script src="../js/vue.js"></script>
<script charset="utf-8" type="text/javascript"
  src="https://res2.wx.qq.com/open/js/jweixin-1.4.0.js?v=202004246"></script>
<script charset="utf-8" src="https://mapapi.qq.com/c/=/jsapi_v2/2/4/130/main.js,jsapi_v2/2/4/130/mods/convertor.js"
  type="text/javascript"></script>
<!-- key 需要自己申请 -->
<script charset="utf-8" src="https://map.qq.com/api/js?v=2.exp&key=XXXXXXXXXXXXXXXXXXXXXXXXXXX"
  type="text/javascript"></script>
<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>


<body>
  <div id="vm">
    <!--地图 -->
    <div id="map-box" v-show="mdMapShow">
      <div class="page-store-map">

        <!-- 1 搜索地点 -->
        <div class="search-place-box">
          <div class="search-place-bg" style="display: ;"><svg t="1574479404611" viewBox="0 0 1024 1024" version="1.1"
              xmlns="http://www.w3.org/2000/svg" p-id="1224" data-spm-anchor-id="a313x.7781069.0.i1" width="26"
              height="26" class="icon">
              <path
                d="M1011.369332 960.985828 838.196247 775.139096c70.193689-84.783988 108.795868-190.480262 108.795868-301.721833 0-261.016759-211.775264-473.417263-472.103338-473.417263-260.252349 0-472.030683 212.362642-472.030683 473.417263 0 261.041318 211.778334 473.40089 472.064452 473.40089 68.193125-0.038886 133.954875-14.310937 195.437158-42.384319 18.262946-8.343015 26.319435-29.950126 18.010189-48.223305-8.311293-18.352997-29.960359-26.472931-48.080042-18.063401-52.039213 23.743774-107.667162 35.799344-165.402097 35.840276C254.653841 873.986381 75.483158 694.290743 75.483158 473.417263c0-220.8612 179.164542-400.583444 399.405619-400.583444 220.274846 0 399.476227 179.695638 399.476227 400.583444 0 103.975073-39.546691 202.480574-111.302969 277.386588-13.901615 14.496156-13.429871 37.544081 0.980327 51.501978 1.089821 1.063215 2.509147 1.458211 3.745301 2.362814 0.985444 1.455141 1.489934 3.134387 2.720971 4.446265l187.807387 201.551412c7.123234 7.673773 16.812921 11.543917 26.508747 11.543917 8.893554 0 17.793248-3.241834 24.802896-9.852392C1024.260943 998.714104 1025.059122 975.666178 1011.369332 960.985828L1011.369332 960.985828 1011.369332 960.985828zM1011.369332 960.985828"
                p-id="1225" fill="#999999"></path>
            </svg><span>搜索地点</span></div>
          <input type="search" v-model="currentAddress" :class="{ isTransparent: currentAddress == '' }"
            v-on:keyup.enter="searchAddress()">
        </div>

        <!-- 2 输入经纬度 -->
        <div class="search-jwd-box">
          <input maxlength="20" type="text" id="longitude" v-model="currentLong" placeholder="请输入经度">
          <input maxlength="20" type="text" id="latitude" v-model="currentLat" placeholder="请输入纬度">
          <input type="button" value="搜索" v-on:click="searchLocationByLongLat">
        </div>
        <!-- 3 地图显示 -->
        <div id="mapContainer" style="height: 250px; background-color: #ccc;"></div>
        <!-- 4 搜索出来的列表 -->
        <ul class="lacation-list">
          <li v-for="(position, index) in positionList" :key="index" :class="position.id == activeId ? 'active' : ''"
            v-on:click="changeActiveId(position.id, position.latLng)">
            <h3>{{ position.name }}</h3>
            <p>{{ position.address }}</p>
          </li>
        </ul>

      </div>
    </div>
  </div>

  <script>
    var vm = new Vue({
      el: '#vm',
      data: {
        province: {
          value: 7,
          name: '广东省'
        },
        city: {
          value: 8,
          name: '广州市'
        },
        district: {
          value: 10,
          name: '白云区'
        },
        mdMapShow: true,
        markers: [],
        currentAddress: '', //搜索的地点
        currentLat: '',
        currentLong: '',
        positionList: [],
        activeId: '',
        searchKey: '瑶台'
      },
      created() {

      },
      mounted() {
        this.mapInit(); // 地图初始化
        this.searchAddress(this.searchKey);
      },
      computed: {},
      watch: {},
      methods: {
        // 搜索地址
        searchAddress(searchKey) {
          // 设置搜索的范围、关键字等属性、页码、每页数量
          let keyword;
          if (searchKey) {
            this.currentAddress = searchKey;
          }
          keyword = this.currentAddress;
          if (keyword.trim() == '') {
            return;
          }

          let city = this.city.name;
          let pageIndex = 0;
          let pageCapacity = 20;
          this.clearOverlays(this.markers);
          // 根据输入的城市设置搜索范围
          this.searchService.setLocation(city);
          // 设置搜索页码
          this.searchService.setPageIndex(pageIndex);
          // 设置每页的结果数
          this.searchService.setPageCapacity(pageCapacity);
          // 根据输入的关键字在搜索范围内检索
          this.searchService.search(keyword);
        },
        searchLocationByLongLat() { // 根据经纬度搜索地址
          let _this = this;
          let { currentLong: Longitude, currentLat: Latitude } = this;

          // 经纬度验证
          if (/^[\-]?[1-9]\d{0,2}\.[0-9]+$/.test(Longitude) && /^[\-]?[1-9]\d{0,1}\.[0-9]+$/.test(Latitude)) {
            if (!/^[\-]?[1-9]\d{0,2}\.[0-9]{4,}$/.test(Longitude) || !/^[\-]?[1-9]\d{0,1}\.[0-9]{4,}$/.test(Latitude)) {
              _this.$toast('经纬度需精确到小数点后至少4位。');
              return;
            } else if (Longitude > 180 || Latitude > 90) {
              _this.$toast('纬度、经度格式不正确!纬度范围-90~90,经度范围-180~180。');
              return;
            }
          } else {
            if (!/^[\-]?0\.[0-9]{4,}$/.test(Longitude) || !/^[\-]?0\.[0-9]{4,}$/.test(Latitude)) {
              _this.$toast('纬度、经度格式不正确!纬度范围-90~90,经度范围-180~180。');
              return;
            }
          }

          var isScoped = 2;
          $.ajax({
            url: 'https://apis.map.qq.com/ws/geocoder/v1',
            data: {
              location: Latitude + ',' + Longitude,
              get_poi: 0,
              key: 'JHIBZ-CTWR5-UJFIK-Q4HGE-4Z7XX-C7BLV', //改为自己申请的key
              output: 'jsonp'
            },
            async: false,
            dataType: 'jsonp',
            success: function (res) {
              if (res.status == 0) {
                var returnData = res.result.address_component;
                if (returnData.hasOwnProperty('province')) { // 中国
                  if ((returnData.province.indexOf(_this.sheng) !== -1) && (returnData.city.indexOf(_this.shi) !== -1)) { // 省、市
                    isScoped = 1;
                  } else { // 香港澳门台湾
                    if ((_this.sheng.indexOf('香港') !== -1) && (returnData.province.indexOf('香港') !== -1)) {
                      isScoped = 1;
                    } else if ((_this.sheng.indexOf('澳门') !== -1) && (returnData.province.indexOf('澳门') !== -1)) {
                      isScoped = 1;
                    } else if ((_this.sheng.indexOf('台湾') !== -1) && (returnData.province.indexOf('台湾') !== -1)) {
                      isScoped = 1;
                    } else {
                      isScoped = 0;
                    }
                  }
                } else {
                  if (_this.sheng.indexOf('海外') !== -1) {
                    isScoped = 3; // 是海外
                  } else {
                    isScoped = 0; // 海外经纬度,但选择的不是海外
                  }
                }
              } else {
                //请求来源未被授权,此次请求无来源信息等
                isScoped = 2;
                alert(res.message);
              }

              if (isScoped == 0) {
                alert('所输入的经纬度和地址不在同一范围内,请检查后重新输入。');
                return;
              }
              if (isScoped == 2) {
                return;
              }
              console.log(res.result);
              _this.activeId = 'abc';
              _this.positionList = [{
                address: res.result.address,
                name: res.result.formatted_addresses.recommend,
                id: 'abc',
                latLng: {
                  lat: Latitude,
                  lng: Longitude
                }
              }];
              console.log(_this.positionList);

              var latLng = new qq.maps.LatLng(Latitude, Longitude);
              // 调用获取位置方法
              _this.geocoder.getAddress(latLng);
            }
          });
        },
        mapInit() {
          let _this = this;
          // 初始地址
          var center = new qq.maps.LatLng(23.12463, 113.36199);
          _this.map = new qq.maps.Map(document.getElementById('mapContainer'), {
            center: center,
            zoom: 15
          });

          // 设置Poi检索服务,用于本地检索、周边检索
          _this.searchService = new qq.maps.SearchService({
            // 检索成功的回调函数
            complete: function (results) {
              // 设置回调函数参数
              var pois = results.detail.pois;
              var latlngBounds = new qq.maps.LatLngBounds();
              var positionList = [];
              for (var i = 0, l = pois.length; i < l; i++) {
                var poi = pois[i];

                // 经纬度至少要4位小数
                if (poi.latLng.lng.toString().split(".")[1].length < 4) {
                  console.log(poi.latLng.lng.toString().split(".")[1].length);
                  poi.latLng.lng = poi.latLng.lng.toFixed(4);
                }
                if (poi.latLng.lat.toString().split(".")[1].length < 4) {
                  poi.latLng.lat = poi.latLng.lat.toFixed(4);
                }

                if (i == 0) { // 只标注第一个点
                  // 扩展边界范围,用来包含搜索到的Poi点
                  latlngBounds.extend(poi.latLng);

                  _this.currentLat = poi.latLng.lat;
                  _this.currentLong = poi.latLng.lng;

                  var marker = new qq.maps.Marker({
                    map: _this.map
                  });
                  marker.setPosition(pois[0].latLng);

                  _this.markers.push(marker);
                  _this.activeId = pois[0].id
                }

                positionList.push({
                  address: poi.address || '',
                  name: poi.name || '',
                  id: poi.id,
                  latLng: poi.latLng || { lat: '', lng: '' }
                });
              }
              _this.positionList = positionList; // 更新一下视图层的列表
              // 调整地图视野
              _this.map.fitBounds(latlngBounds);
            },
            // 若服务请求失败,则运行以下函数
            error: function () {
              console.log('搜索不到结果');
            }
          });
          // 调用地址解析类
          _this.geocoder = new qq.maps.Geocoder({
            complete: function (result) {
              _this.clearOverlays(_this.markers);
              // 调整地图包含该点
              var latlngBounds = new qq.maps.LatLngBounds();
              latlngBounds.extend(result.detail.location);
              _this.map.fitBounds(latlngBounds);

              var marker = new qq.maps.Marker({
                map: _this.map
              });
              marker.setPosition(result.detail.location);
              _this.markers.push(marker);
            }
          });
        },
        clearOverlays(overlays) { // 除地图上的marker
          var overlay;
          while ((overlay = overlays.pop())) {
            overlay.setMap(null);
          }
        },
        changeActiveId(id, latLng) {
          var _this = this;
          this.activeId = id;

          this.clearOverlays(this.markers);

          this.currentLat = latLng.lat;
          this.currentLong = latLng.lng;

          // 调整地图包含该点
          var latlngBounds = new qq.maps.LatLngBounds();
          latlngBounds.extend(latLng);
          this.map.fitBounds(latlngBounds);

          var marker = new qq.maps.Marker({
            map: _this.map
          });
          marker.setPosition(latLng);

          this.markers.push(marker);
        },
        toStoreRegister() { // 确定修改
          // 要拿来覆盖的数据有: 地址,以搜索列表的结果为准,不以输入框的结果为准
          // 若是搜索地址,则搜索结果的经纬度会自动代入经纬度输入框
          // 若是搜索经纬度,则搜索结果只有一个点,并且经纬度就是输入框的值
          // 直接取输入框的经纬度来用,防止用户输入了经纬度不点击按钮,将经纬度是否在省市区内的逻辑改到提交那里。
          let { positionList, currentLat, currentLong } = this;

          // 拿到当前active的搜索结果的地址,若列表为空,则不覆盖原来的地址
          for (var i = 0; i < positionList.length; i++) {
            if (positionList[i].id == this.activeId) {
              // console.log(positionList[i].latLng.lat, positionList[i].latLng.lng);
              // 去除省市区
              var myBossAddress = positionList[i].address + positionList[i].name;
              var shengshiqu = this.sheng + this.shi + this.qu;
              var shengshi = this.sheng + this.shi;

              if (myBossAddress.includes(shengshiqu)) {
                myBossAddress = myBossAddress.replace(shengshiqu, '');
              } else if (myBossAddress.includes(shengshi)) {
                myBossAddress = myBossAddress.replace(shengshi, '');
              }

              console.log(myBossAddress, shengshiqu);
              this.$store.commit('changeBossAddress', myBossAddress);

              break;
            }
          }
          // 直接取输入框的经纬度来覆盖
          this.$store.commit('changeBossLatLong', { bossLatitude: currentLat, bossLongitude: currentLong });

          // 隐藏当前组件
          this.$parent.isShowStoreMap = false;
          console.log(this.$store.state.bossAddress, this.$store.state.bossLatitude, this.$store.state.bossLongitude);
          this.$setTitle("注册门店");
        },

      }

    });

  </script>


  <style>
    [v-cloak] {
      display: none;
    }

    html {
      overflow-x: auto;
      overflow-y: scroll;
    }

    body,
    dl,
    dt,
    dd,
    ul,
    ol,
    li,
    pre,
    form,
    fieldset,
    input,
    p,
    blockquote,
    th,
    td {
      font-weight: 400;
      margin: 0;
      padding: 0;
    }

    h1,
    h2,
    h3,
    h4,
    h4,
    h5 {
      margin: 0;
      padding: 0;
    }

    #map-box {
      position: relative;
      z-index: 1000;
    }

    #map-box .page-store-map {
      position: fixed;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      z-index: 100;
      display: flex;
      flex-direction: column;
      background-color: #fff;
    }

    #map-box .page-store-map .search-place-box {
      width: 100%;
      height: 50px;
      position: relative;
    }

    #map-box .page-store-map .search-place-box .search-place-bg {
      margin: 10px;
      width: calc(100% - 20px);
      height: 30px;
      position: absolute;
      background-color: #F0F0F0;
      line-height: 30px;
      text-align: center;
      color: #ABABAB;
      font-size: 14px;
      border-radius: 5px;
      z-index: 1;
      display: flex;
      justify-content: center;
      align-items: center;
    }

    #map-box .page-store-map .search-place-box .search-place-bg svg {
      width: 13px;
      height: 13px;
      margin-right: 16px;
      margin-top: -1px;
    }

    #map-box .page-store-map .search-place-box input {
      margin: 10px;
      height: 30px;
      width: calc(100% - 20px);
      position: absolute;
      z-index: 2;
      text-align: center;
      font-size: 14px;
      padding: 0 10px;
      line-height: normal;
      border-radius: 5px;
      background-color: #fff;
      box-sizing: border-box;
    }

    #map-box .page-store-map .search-place-box input.isTransparent {
      background-color: transparent;
    }

    #map-box .page-store-map .search-jwd-box {
      height: 30px;
      padding: 10px 0 10px 15px;
      background-color: #F7F7F7;
      display: flex;
      justify-content: space-between;
      border-bottom: 5px solid #fff;
    }

    #map-box .page-store-map .search-jwd-box input {
      background-color: #fff;
      border-radius: 3px;
      box-sizing: border-box;
      border: 1px solid #E7E7E7;
    }

    #map-box .page-store-map .search-jwd-box input:first-child {
      padding: 0 10px;
      width: calc((100% - 100px)/2);
    }

    #map-box .page-store-map .search-jwd-box input:nth-child(2) {
      padding: 0 10px;
      width: calc((100% - 100px)/2);
    }

    #map-box .page-store-map .search-jwd-box input:last-child {
      width: 70px;
      border-color: #3C77DA;
      color: #3C77DA;
      margin-right: 15px;
      text-align: center;
    }

    #map-box .page-store-map #container {
      height: 250px;
    }

    #map-box .page-store-map ul {
      margin-top: 10px;
      padding-bottom: 10px;
      flex: 1;
      overflow-y: auto;
    }

    #map-box .page-store-map ul li {
      margin-bottom: 10px;
      padding-left: 30px;
      padding-right: 10px;
      position: relative;
    }

    #map-box .page-store-map ul li h3 {
      line-height: 20px;
      color: #333;
      font-size: 14px;
    }

    #map-box .page-store-map ul li p {
      line-height: 15px;
      color: #999;
      font-size: 12px;
    }

    #map-box .page-store-map ul li:last-child {
      margin-bottom: 0;
    }

    #map-box .page-store-map ul li:after {
      content: "";
      display: block;
      width: 12px;
      height: 12px;
      border: 1px solid #ccc;
      border-radius: 50%;
      position: absolute;
      top: 10px;
      left: 10px;
    }

    #map-box .page-store-map ul li.active:after {
      top: 10px;
      border-radius: 0;
      width: 13px;
      height: 15px;
      border: 0 none;
      background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAYAAACpSkzOAAAEBUlEQVRIS6WVa2gcVRTH/+fu1oL2a5UWP6jZ7GySnUDSdGYSQRCK2GLrI1oV64tqozYFEWpbVKxQsVYQxFZMfaHiqzSttiUVKQiCzcw2TWDvJNmZpNoPUtF+rULt7j0yM9ln9xHxfpq553/u7zzumSG0WJ0/di4T16luodhQQDsJ3Bi4sMJvAphTgjLqL5GduX3mUrOjqJGxY6JjRexKYYhi9DQYK5vGQ7jABf6gsCQ2Mts3+3s9bV1Ql53oFCQOAdQVRs98RBBNMvNU/p/YVLAXv6bQQ0Q9irmXiO6LDudpxWrjtDU/Uwu7ClQN4T+Ysd21/M+bZZS2k48S4S2AbmgEqwJVQhj0mWvmHm/Vw0p72kl9SuDH6sGqQOmMdowY60E4KQ1vXT1I+udEW7Dv3jp/rp5dz2hjYKxlwnHX8DYUNSVQ2kndReDjgSF/Waycva3c1PREog352AtECOA3LTifZ8YY4oW33b4ytOOnjhXxpepC2DHQetfMnQiey6CMdpgYg2AelpZ/oBhJOpMaIOZvASxvUMaLTHSPa+ROF+26ndwKov1MGHUN7/4SqGcysTx/JfZnKCTVJo25X4LHYIZi16pTAJvNe0VO4W+xpjhLeqb9FrAISxtfUrh+qnf+YphR97i2gQW+A+GcNLxEKRtH20zAh4u5EAw85ZreR6WsMto8GG2kcHe23zsWgTLJ55jpADNGXStKNVh6JjkCpi2LAYH4oDT8oVKQtnaYCINEvDVr+O+FIN1O7gTRGwD2SdPbURR328lRLg1ji+IxH8la/mApSEd7E8CLYN4lLX9vCOqykw8Joq/oKnFqGOB3F5URaJs0c/trg1TMD09b/tcR6GxXQuTzcwDOS9O7uSQe7+hloYLbtLQF7DIpMZDtn52syOjXYBRUPN4+vWp6vnS9i4NGSlnZ/jmn7JAcBqhFVrxNmn45m/F2k4WwKwe/DLJTW0A8AuB7aXprKzNI26k7iHgUwLKazC4x06Br5X6o3Ncd7SSAO8E0JK3cwXBqagQTAFYx8Lprei9X2U6ndMTUGgCrF/bPoCBOyYGcrArK0fYQ8BKAs9L0+oq2atB46gkI/iQwMuFB1/AOLe4iRKp0RttIjG+iN3pEmrkv64JC8XhyNwl6dUH8jDRzQTlbLt1JDQH8fsTgXdLw91Y61f3xdTvadgb2LQh3StMLZqLh0h0tmL3oYMIr0vD21Iob/sp1W3sShI/DMip+ze33d9cjVVcAO6TpFQOskjcEBSrd0R4AEPapHqwSQozns5b3TqO0m4KawSohDDzrml7UnwarJagWBqDYr/CbyIzNruWFJf7foDqw6EzCJml4X7SCRNL/sPQzyXWs6N7QUfBRudofW6z7v/t0vyrEJNCZAAAAAElFTkSuQmCC) no-repeat;
      background-size: contain;
    }

    #map-box .page-store-map .submit-box {
      height: 60px;
      display: flex;
      justify-content: space-between;
      padding: 0 15px;
      align-items: center;
      box-shadow: 0px 0px 8px 0px rgba(0, 0, 0, 0.1);
    }

    #map-box .page-store-map .submit-box div {
      margin: 10px;
      box-sizing: border-box;
      font-size: 15px;
      height: 32px;
      line-height: 32px;
      text-align: center;
      border-radius: 15px;
    }

    #map-box .page-store-map .submit-box .fanhui {
      flex: 1;
      border: 1px solid #DEDEDE;
      color: #333;
    }

    #map-box .page-store-map .submit-box .queding {
      flex: 2;
      background-color: #2DC927;
      color: #fff;
      font-weight: bold;
    }

    .icon-map {
      display: inline-block;
      vertical-align: middle;
      width: 15px;
      height: 21px;
      background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAApBAMAAADQYYSEAAAAA3NCSVQICAjb4U/gAAAAHlBMVEX4+fjz9PPx8fHa9tns7OzQ1s+g555n2GU6yzlESszYAAAACXBIWXMAAAsSAAALEgHS3X78AAAAH3RFWHRTb2Z0d2FyZQBNYWNyb21lZGlhIEZpcmV3b3JrcyA4tWjSeAAAAVlJREFUKJFNUrFOwzAQvbSh6QgTYUMICXXrxhqhotYbAwNjJxBbUCvabK0EajMiAvH9Le+d44iTEvvsd++eny2CSF5q9e+n0sWgUkZ72eWVHu6vHrfahjTXDxsXurfiuo04T4qxFl2e6o6rTeQVB+SJlmwxI3mmD5J5TEbov8RYl3LRkFKPSjL3JdWOlG9yTrJxS4i8ktL9CovrwspsLqkXncpASc7/UAX/1Ft3IJOQa8wHyIt/eOyQq+fDx/4u9kN/SILuldxSz6ThEh1ScwfgFGeSFOcpeFaKo0vJjNbkFDLx0eik/jaX9hKNNeecn1o6rJvOxjC6aOyTTVL9jPdlQOe7+xqVOTzOdJ/RUhj3I7iiyssENlLaCpsbQG4o0pnxlckfgcjkAlBKEMzjIJ6DpOBPH/SnfyZ8OC0q2/7+K7IsVA/ru7Pr+VbDw5lrjHWH2xyRHDes+wOYgYGkyS5JZAAAAABJRU5ErkJggg==) no-repeat;
      background-size: contain;
    }
  </style>

</body>

</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值