uniapp 自定义map组件
1、地图附近相关数据引用高德
2、key自己申请
3、附带城市选择
4、项目引入的是graceui,请自行修改
5、调用相关自行处理
注意:直接引用不可用,uniapp sdk升级后中心点和maekers相关只改为可用,没做优化 仅限参考、仅限参考、仅限参考
在这里插入图片描述

addressChoose.vue

<template>
    <aPage :footerHeight="0">
        <!-- 页面头部 -->
        <view slot="gHeader" class="grace-header-body" style="background-color: #fff;">
            <text class="grace-header-icons grace-icons icon-back grace-block" @tap="closeChoose"></text>
            <view class="grace-header-content"><view style="width:100%;text-align: center;">选择位置</view></view>
            <text class="mapSure" @tap="sureMap" style="margin-right: 20rpx;">完成</text>
        </view>
        <!-- 页面主体 -->
        <view slot="gBody" style="position: relative;" class="grace-bg-body">
            <!-- 页面主体 -->
            <view class="grace-body gracedy" style="position: relative; ">
                <view class="serchCont">
                    <view class="searchbox">
                        <view class="cityName" @tap="shouwCity(true)">
                            <text class="city">{{ city }}</text>
                            <text class="icon-arrow-down grace-header-icons grace-icons grace-gray seliocn"></text>
                        </view>
                        <view class="shu">|</view>
                        <view class=""><graceSearch @inputting="onKeyInput" @clear="clearText" @confirm="onKeyInput" :kwd="serarchText" placeholder="搜索地点"></graceSearch></view>
                    </view>
                </view>
                <view class="" style="width: 100%; height: 600rpx;overflow: hidden;" v-show="!mapHiden" @touchmove.stop="">
                    <!-- #ifdef APP-PLUS -->
                    <map
                        id="map1"
                        ref="map1"
                        style="width: 100%; height: 600rpx;"
                        :latitude="latitude"
                        :longitude="longitude"
                        @regionchange="selectMap"
                        show-location
                        :scale="16"
                    ></map>
                    <!-- #endif -->
                    <!-- #ifdef H5 -->
                    <map
                        id="map1"
                        ref="map1"
                        style="width: 100%; height: 600rpx;"
                        :markers="covers"
                        :latitude="latitude"
                        :longitude="longitude"
                        @regionchange="selectMap"
                        show-location
                        :scale="15"
                    ></map>
                    <!-- #endif -->
                </view>
                <view class="">
                    <view class="tmapList" :class="mapHiden ? 'tmapList1' : ''" v-if="!mapHiden">
                        <view class="mapSing" v-for="(item, index) in mapResult" :key="index" @tap="selectAddress(item)">
                            <view class="mapleflt">
                                <view class="weiz">{{ index == 0 && !mapHiden && !showads ? '我的位置' : item.name }}</view>
                                <view class="adress">{{ typeof item.address == 'string' ? item.address : '' }}</view>
                            </view>
                            <view class="mapright"><image src="/static/img/map/currentPos.png" mode="" v-if="item.check"></image></view>
                        </view>
                    </view>
                    <view class="tmapList" :class="mapHiden ? 'tmapList1' : ''" v-else>
                        <view class="mapSing" v-for="(item, index) in keyResult" :key="index" @tap="keySelect(item)">
                            <view class="mapleflt">
                                <view class="weiz">{{ item.name }}</view>
                                <view class="adress">{{ typeof item.address == 'string' ? item.address : '' }}</view>
                            </view>
                            <view class="mapright"><image src="/static/img/map/currentPos.png" mode="" v-if="item.check"></image></view>
                        </view>
                    </view>
                </view>
            </view>

            <selectCity v-show="showModule" ref="selectCity" @chooseCity="chooseCity" style="position: fixed;top: 0;left: 0;z-index: 9999999;background-color: #fff;"></selectCity>
        </view>
    </aPage>
</template>

<script>
import selectCity from '@/components/selectCity.vue';
export default {
    data() {
        return {
          key: '',
          cities: [],
	      addressName: "",
	      weather: {
	        hasData: false,
	        data: [],
	      },
	      title: "map",
	      address: {},
	      latitude: 31.972952,
	      longitude: 118.78025,
	      searchNeary: 4000,
	      covers: [
	        {
	          width: 20,
	          height: 20,
	          latitude: 31.972952,
	          longitude: 118.78025,
	          iconPath: "/static/images/common/location.png",
	          address: "",
	          name: "",
	        },
	      ],
	      icon: "https://p-yy-yjy.oss-cn-shanghai.aliyuncs.com/static/images/20220106/1141641459414_.pic.jpg",
	      map: null,
	      mapCtx: null,
	      keyResult: [],
	      mapResult: [],
	      mapHiden: false,
	      inputClearValue: "",
	      showClearIcon: false,
	      serarchText: "",
	      keyUser: {},
	      shoeLoding: false,
	      showModule: false,
	      mapCtx: {},
	      city: "南京市",
	      showads: false,
	      tindex: 0,
	      searchKey: "",
	      selectKey: {},
	      haveData: false,
        };
    },
   components: {
    selectCity,
  },
  onReady() {
    console.log("onReady");
    // #ifdef APP-PLUS
    this.newMap();
    // #endif
  },
  onLoad: function (e) {
    this._select = e.s;
    // if (this._select) {
    //   this.obtainAddres(this._select);
    // }
    this.obtainAddres(this._select);

    this.haveData = true;
  },
  onShow() {},
  methods: {
    loadScrpit(address, bol) {
      console.log("addressChoose loadScrpit");
      let self = this;
      var map = new AMap.Map("map1", {
        enableHighAccuracy: true, //是否使用高精度定位,默认:true
        zoomToAccuracy: true,
        zoom: 15,
        scrollWheel: false,
        dragEnable: true, //是否可拖动
        resizeEnable: true,
        rotateEnable: true,
        buttonPosition: "RB",
        buttonOffset: new AMap.Pixel(10, 20), //定位按钮与设置的停靠位置的偏移量,默认:Pixel(10, 20)
        center:
          address && address.lng
            ? [address.lng, address.lat]
            : [118.78025, 31.972952], //初始化地图中心点
      });
      self.map = map;
      console.log("addressChoose map init ");
      if ("https:" == location.protocol) {
        map.plugin(["AMap.Geolocation"], function () {
          let geolocation = new AMap.Geolocation({
            enableHighAccuracy: true, //  是否使用高精度定位,默认:true
            timeout: 10000, //  超过10秒后停止定位,默认:无穷大
            maximumAge: 0, // 定位结果缓存0毫秒,默认:0
            convert: true, // 自动偏移坐标,偏移后的坐标为高德坐标,默认:true
            showButton: true, //  显示定位按钮,默认:true
            buttonPosition: "LB", // 定位按钮停靠位置,默认:'LB',左下角
            buttonOffset: new AMap.Pixel(10, 20), //  定位按钮与设置的停靠位置的偏移量,默认:Pixel(10, 20)
            showMarker: true, //  定位成功后在定位到的位置显示点标记,默认:true
            showCircle: true, //  定位成功后用圆圈表示定位精度范围,默认:true
            panToLocation: true, //  定位成功后将定位到的位置作为地图中心点,默认:true
            zoomToAccuracy: true, //  定位成功后调整地图视野范围使定位位置及精度范围视野内可见,默认:false
          });
          // console.log("addressChoose map Geolocation ");

          map.addControl(geolocation);
          // geolocation.getCurrentPosition()
          AMap.event.addListener(geolocation, "complete", (res) => {
            console.log(
              "addressChoose map Geolocation complete ",
              JSON.stringify(res)
            );
            if (!self.haveData) {
              console.log(
                "addressChoose map setCenter",
                JSON.stringify(res.position)
              );
              map.setCenter(res.position);
              self.setPoint(res.position.lng, res.position.lat, true, true);
              // self.map.setZoomAndCenter(15, [res.position.lng, res.position.lat]); //同时设置地图层级与中心点
            }
          }); //  返回定位信息
          AMap.event.addListener(geolocation, "error", (err) => {
            console.log(
              "addressChoose map Geolocation error ",
              JSON.stringify(err)
            );
            if (!self.haveData) {
              map.setCenter({ lat: 31.972952, lng: 118.78025 });
              self.setPoint(118.78025, 31.972952, true, true);
            }
          }); //  返回定位出错信息
        });
      }
      // console.log("addressChoose map PositionPicker");
      AMapUI.loadUI(["misc/PositionPicker"], function (PositionPicker) {
        // self.obtainAddres(address, 1);
        var positionPicker = new PositionPicker({
          mode: "dragMap",
          map: map,
          timeout: 10000, //超过10秒后停止定位,默认:5s
          buttonPosition: "RB", //定位按钮的停靠位置
          buttonOffset: new AMap.Pixel(10, 20), //定位按钮与设置的停靠位置的偏移量,默认:Pixel(10, 20)
          iconStyle: {
            //自定义外观
            url: self.icon,
            ancher: [24, 40],
            size: [1, 1],
          },
        });
        positionPicker.on("success", function (positionResult) {
          // console.log(positionResult);
          // console.log(
          //   "addressChoose map positionPicker",
          //   JSON.stringify(positionResult)
          // );
          let cityinfo = positionResult.address;
          // self.mapResult = positionResult.regeocode.pois;
          // self.getMapSta1(positionResult.regeocode.pois,0)
          if (!self.mapHiden || address) {
            // self.obtainAddres(positionResult.position,1)
            if (address && address.longitude && !address.lng) {
              address.lng = address.longitude;
              address.lat = address.latitude;
            }
            if (address && address.lng && self.haveData) {
              self.address = address;
              self.selectKey = self.address || "";
              self.address.location = self.address.lng + "," + self.address.lat;
              if (!self.selectKey.name)
                self.selectKey.name = self.selectKey.addr;
              self.haveData = false;
              self.setPoint(address.lng, address.lat, true, true);
            } else {
              self.setPoint(
                positionResult.position.lng,
                positionResult.position.lat,
                true,
                true
              );
            }
          }
          // self.obtainAddres(positionResult.position,1)
          // console.log(cityinfo);
        });
        positionPicker.on("fail", function (positionResult) {
          self.obtainAddres(positionResult.position, 1);
          console.log(`定位失败:` + positionResult);
        });
        positionPicker.start();
        map.panBy(0, 1);
      });
      return;
    },
    //获取位置信息
    obtainAddres(address, index) {
      let self = this;
      self.getCityList(address);
      // #ifdef APP-PLUS
      if (!self.map) {
        self.newMap();
      }
      // #endif
      if (address && address.lng) {
        console.log("addressChoose address");
        self.address = address;
        self.selectKey = self.address || "";
        self.address.location = self.address.lng + "," + self.address.lat;
        if (!self.selectKey.name) self.selectKey.name = self.selectKey.addr;
        // #ifdef APP
        self.setPoint(address.lng, address.lat, true, true);
        // #endif
        // #ifdef H5
        self.loadScrpit(address, false);
        // #endif
      } else {
        console.log("addressChoose getLocation");
        uni.getLocation({
          // #ifdef APP-PLUS
          type: "gcj02",
          geocode: true,
          // #endif
          success: function (res) {
            console.log("addressChoose success", JSON.stringify(res));
            // #ifdef APP
            self.map.setCenter(
              new plus.maps.Point(res.longitude, res.latitude)
            );
            self.setPoint(res.longitude, res.latitude, true, true);
            // #endif
            // #ifdef H5
            self.loadScrpit(res);
            // #endif
          },
          fail(err) {
            console.log("addressChoose fail");
            // #ifdef APP-PLUS
            let center = self.$refs.map1._map.getCenter();
            // #endif
            // // #ifdef H5
            // let center = self.map.getCenter();
            // // #endif
            // #ifdef APP
            self.setPoint(center.lng, center.lat, true, true);
            // #endif
            // #ifdef H5
            self.loadScrpit();
            // #endif
          },
        });
      }
    },
    //closeChoose
    closeChoose() {
      if (this._select) {
        // this.$app.navBack();
        Page.navBack();
      } else {
        this.$emit("choiceSite", "");
      }
    },
    //显示、关闭城市选择弹窗
    shouwCity(bol) {
      this.showModule = bol;
      this.mapHiden = bol;
      // console.log('显示选择弹窗,success',JSON.stringify(this.cities));
      if (this.showModule) {
        this.$refs.selectCity.cityPinyin(this.cities, this.city);
      }
    },
    // 获取城市
    getCityList(address) {
      var self = this;
      App.client.plt.reqA(0, "M/amap", [], (err, rep) => {
        // self.$plt.Api_M.amap(1, [], function (err, rep) {
        if (rep) {
          let code = "";
          if (address && address.adcode) {
            code = (address && address.adcode + "").substring(0, 4);
          }
          if (code == "1101") {
            code = 1100;
          } else if (code == "3101") {
            code = 3100;
          } else if (code == "5001") {
            code = 5000;
          } else if (code == "1201") {
            code = 1200;
          }
          for (let i = 0, len = rep.cities.length; i < len; i++) {
            if (rep.cities[i].id == code) {
              self.city = rep.cities[i].name;
              // console.log(self.city);
              break;
            }
          }
          self.cities = rep.cities;
          self.key = rep.key;
          // console.log(self.key);
          // console.log(self.cities);

          uni.setStorage({
            key: "cities",
            data: JSON.stringify(self.cities),
            success: function () {
              // console.log('存储成功,success',JSON.stringify(self.cities));
            },
          });
        }
      });
    },
    //接收选择城市
    chooseCity(data) {
      // console.log(data);
      this.shouwCity(false);
      if (data != "") {
        this.city = data;
      }
    },
    // 高德地图查询周边  根据有无经纬度判断是移动中心点还是关键字搜索
    getPoiAround(keywords, centerPoint, city) {
      let self = this;
      let url, location, index;
      // console.log(self.key);
      // console.log("addressChoose 高德地图查询周边 getPoiAround", self.key);

      let data;
      if (!centerPoint[0]) {
        index = 1;
        data = {
          key: self.key,
          keywords: keywords,
          city: self.city,
          citylimit: true,
        };
        url = "https://restapi.amap.com/v3/place/text";
      } else {
        index = 0;
        // console.log(self._centerPoint);
        self._centerPoint = centerPoint;
        location = centerPoint.join(",");
        data = {
          key: self.key,
          keywords: keywords,
          location: location,
          // city:this.city
        };
        url = "https://restapi.amap.com/v3/place/around";
      }
      // console.log(
      //   "addressChoose 高德地图查询周边 getPoiAround request",
      //   JSON.stringify(data)
      // );
      uni.request({
        url: url,
        data: data,
        success: function (res) {
          // console.log(
          //   "addressChoose 高德地图查询周边 request success",
          //   JSON.stringify(res.data)
          // );
          // console.log(res.data);
          // console.log(res.data.infocode);
          if ((res.data.infocode = 10000)) {
            if (res.data.pois) {
              let pois = res.data.pois;
              for (var i = 0, len = pois.length; i < len; i++) {
                pois[i].check = false;
              }
            }
            let poisData = res.data.pois;
            self.tindex++;
            // console.log(self.tindex);
            // uni.removeStorageSync('selectKey');
            // self.getMapSta1(poisData, index);
            // 如果有选中的搜索地址,在数组前面插入
            if (self.selectKey.name) {
              if (self.selectKey.name != poisData[0].name) {
                if (!poisData[0].address)
                  poisData[0].address = poisData[0].name;
                self.selectKey.check = false;
                poisData.unshift(self.selectKey);
              }
              self.showads = true;
              // 由于此处会改变中心点,第二此请求时候清除缓存
              if (self.tindex >= 2) {
                self.selectKey = {};
              }
              self.getMapSta1(poisData, index);
            } else {
              self.showads = false;
              self.selectKey = {};
              self.getMapSta1(poisData, index);
            }
          }
        },
        fail: (err) => {
          // console.log(
          //   "addressChoose 高德地图查询周边 request fail",
          //   JSON.stringify(err)
          // );
        },
      });
    },
    //公共赋值
    getMapSta1(data, index) {
      // console.log(
      //   "addressChoose 高德地图查询周边 getMapSta1",
      //   JSON.stringify(data),
      //   index
      // );
      let self = this;
      for (var i = 0, len = data.length; i < len; i++) {
        if (data[i].location && data[i].location.length <= 0) {
          data.splice(i, 1);
        }
        len -= 1;
      }
      if (index == 0) {
        self.mapResult = data;
        self.mapHiden = false;
        if (self.tindex >= 2) {
          self.selectAddress(data[0]);
          self.mapHiden = false;
        }
      } else {
        let flage = true;
        for (var i = 0, len = data.length; i < len; i++) {
          if (
            data[i].name == self.searchKey ||
            data[i].address == self.searchKey
          ) {
            flage = false;
          }
        }
        if (flage) {
          let lens = data.map((item) => item.address.length);
          let minLen = Math.min.apply(null, lens);
          let str = data[lens.indexOf(minLen)];
          data.unshift(JSON.parse(JSON.stringify(str)));
          data[0].name = self.searchKey;
          // console.log(data);
        }

        self.keyResult = data;
        self.mapHiden = true;
      }
      self.shoeLoding = false;
    },
    //app 端初始化
    newMap() {
      let self = this;
      var mapCtx = uni.createMapContext("map1", self);
      self.mapCtx = mapCtx;
      self.map = mapCtx.$getAppMap();
    },
    //中心点经纬度赋值和移动marker
    setPoint(lng, lat, cover, center) {
      // console.log("addressChoose map setPoint", lng, lat, cover, center);
      let self = this;
      if (cover) {
        self.covers[0].longitude = lng;
        self.covers[0].latitude = lat;
        self.getPoiAround(
          "",
          [self.covers[0].longitude, self.covers[0].latitude],
          ""
        );
      }
      // 设置maker标记
      // #ifdef APP-PLUS
      self.map.removeOverlay(self.marker);
      self.marker = new plus.maps.Marker(new plus.maps.Point(lng, lat));
      self.marker.setIcon("./static/images/common/location.png");
      var bubble = new plus.maps.Bubble("打造最好的HTML5移动开发工具");
      self.marker.setBubble(bubble);
      self.map.addOverlay(self.marker);
      // #endif
      // #ifdef H5
      let covers = self.covers;
      covers[0].longitude = lng;
      covers[0].latitude = lat;
      self.covers = JSON.parse(JSON.stringify(covers));
      self.map.clearMap();
      let marker = new AMap.Marker({
        clickable: true, //是否可点击
        position: new AMap.LngLat(lng, lat), //标记位置
        icon: new AMap.Icon({
          //自定义图标
          size: new AMap.Size(30, 30), //图标显示大小
          image:
            "https://p-yy-yjy.oss-cn-shanghai.aliyuncs.com/static/images/20220106/location.png", //图标路径
          imageSize: new AMap.Size(30, 30), //图标缩放大小
        }),
      });
      self.map.add(marker);
      // #endif
      //设置中心点
      if (center) {
        self.longitude = lng;
        self.latitude = lat;
        // #ifdef H5
        // self.$ref.map1.centerChange()

        // self.map.setZoomAndCenter(16, [lng, lat]); //同时设置地图层级与中心点
        // #endif
        // #ifdef APP-PLUS
        self.map.setCenter(new plus.maps.Point(lng, lat));
        // #endif
      }
    },
    //关键字搜索选择地址
    keySelect(item) {
      let self = this;
      if (item.location.length <= 0) return;
      let poi = item.location.split(",");
      self.setPoint(poi[0], poi[1], true, true);

      try {
        self.map.centerAndZoom(15, [poi[0], poi[1]]); //同时设置地图层级与中心点
      } catch (error) {
        self.map.setZoomAndCenter(15, [poi[0], poi[1]]);
      }
      // self.map.centerAndZoom(15, [poi[0], poi[1]]); //同时设置地图层级与中心点
      self.mapHiden = false;
      self.serarchText = "";
      self.keyUser = item;
      self.keyResult = [];
      //记住搜索选择的地址
      // uni.setStorageSync('selectKey',JSON.stringify(item));
      self.selectKey = item;
      self.tindex = 0;
    },
    //选择地址  移动中心点附近列表
    selectAddress(item) {
      let self = this;
      if (!item || item.location.length <= 0) return;
      self.covers[0].name = item.name == item.address ? "" : item.name;
      self.covers[0].address =
        (item.pname ? item.pname : "") +
        (item.cityname ? item.cityname : "") +
        (item.adname ? item.adname : "") +
        (item.address ? item.address : "");
      // console.log("选中地址");
      // console.log(self.covers[0]);
      // console.log(item.location);
      let poi = [];
      if (item.location && item.location.lng) {
        self.covers[0].longitude = item.location.lng;
        self.covers[0].latitude = item.location.lat;
        poi = [item.location.lng, item.location.lat];
      } else {
        poi = item.location.split(",");
        self.covers[0].longitude = poi[0];
        self.covers[0].latitude = poi[1];
      }
      //当前数据不给不选中
      // console.log(item.id);
      // console.log("-------------------");
      // console.log(self.mapResult.length);
      for (var i = 0, len = self.mapResult.length; i < len; i++) {
        // console.log(item.id +'---------------'+ self.mapResult[i].id)
        if (item.id == self.mapResult[i].id) {
          self.mapResult[i].check = true;
        } else {
          self.mapResult[i].check = false;
        }
      }
      //当前选中
      self.mapHiden = false;
      self.$forceUpdate();
      //清空当前关键字搜索列表
      self.keyResult = [];
      self.setPoint(poi[0], poi[1], false);
    },
    //清空关键字搜索 ,关闭搜索列表
    clearText(e) {
      this.shouwCity();
    },
    //关键字搜索
    onKeyInput(e) {
      let self = this;
      if (e == "") return;
      self.searchKey = e;
      self.getPoiAround(e, ["", ""], "");
    },
    //移动获取中心点
    selectMap(e) {
      let self = this;
      console.log("移动中心点");
      // #ifdef H5
      console.log(self.$refs.map1._map.getCenter());
      let center = self.$refs.map1._map.getCenter();
      self.setPoint(center.lng, center.lat, true, true);
      // #endif

      // #ifdef APP-PLUS
      if (!self.map || !self.mapCtx) {
        self.newMap();
      }
      self.mapResult = [];
      self.searchNeary = 300;
      try {
        // console.log("移动中心点3333333333", self.map);
        // self.map.getCurrentCenter(function (state, point) {
        //   console.log("getCurrentCenter back");
        //   if (0 == state) {
        //     //给经纬度和中心点赋值
        //     try {
        //       console.log("point: " + JSON.stringify(point));
        //       self.setPoint(point.getLng(), point.getLat(), true);
        //     } catch (e) {
        //       console.error(e);
        //     }
        //   } else {
        //     console.log("Failed!");
        //   }

        //   console.log("getCurrentCenter back done");
        // });
        self.mapCtx.getCenterLocation({
          complete(res) {
            if (res.longitude && res.latitude) {
              self.setPoint(res.longitude, res.latitude, true);
            }
          },
        });
      } catch (e) {
        // console.log("移动中心点2222222222");
        console.error(e);
      }
      // #endif
    },
    //确定选择位置
    sureMap() {
      if (this.covers[0].address == "") {
        uni.showModal({
          content: "您尚未选择位置!",
          showCancel: false,
          success: function (res) {
            if (res.confirm) {
              console.log("用户点击确定");
            } else if (res.cancel) {
              console.log("用户点击取消");
            }
          },
        });
      } else {
        // console.log(this.covers[0]);
        if (!this._select) {
          this.$emit("choiceSite", this.covers);
        } else {
          // console.log("执行choiceSite 回调");

          axCc.vueSelf.$callback("abAct.choiceSite", null, this.covers);
          // this.$app.navBack();
          Page.navBack();
        }
      }
    },
  },
};
</script>

<style lang="scss" scoped>
.serchCont {
    background-color: #f5f5f5;
    width: 100%;
    overflow: hidden;
    .searchbox {
        width: calc(100% - 60rpx);
        margin: 10rpx 30rpx;
        height: 80rpx;
        background-color: #fff;
        display: flex;
        justify-content: center;
        align-items: center;
        border-radius: 40rpx;
    }
    .shu {
        color: #f5f5f5;
    }
    .cityName {
        display: flex;
        justify-content: center;
        align-items: center;
        .city {
            display: inline-block;
            width: 84rpx;
            overflow: hidden; //超出的文本隐藏
            text-overflow: ellipsis; //溢出用省略号显示
            white-space: nowrap; //溢出不换行
        }
        .seliocn {
            width: 28rpx;
            height: 28rpx;
            line-height: 36rpx;
            font-size: 24rpx;
        }
    }
}

.tmapList1 {
    height: calc(100vh - 80rpx - 44rpx) !important;
}

.tmapList {
    width: 100%;
    height: calc(100vh - 600rpx - 120rpx - 44rpx);
    overflow-x: hidden;
    overflow-y: scroll;
    border-top: 2rpx solid #ccc;
    position: static;
    -webkit-overflow-scrolling: touch;

    .mapSing {
        width: calc(100% - 20rpx);
        display: flex;
        justify-content: space-between;
        align-items: flex-start;
        border-bottom: 2rpx solid #ccc;
        padding: 20rpx 0;
        margin-left: 20rpx;

        .mapleflt {
            width: calc(100% - 80rpx);
            display: flex;
            flex-direction: column;
            justify-content: flex-start;
            align-items: center;

            view {
                width: 100%;
            }

            .weiz {
                color: #333;
                font-size: 28rpx;
            }

            .adress {
                color: gray;
                font-size: 24rpx;
                margin-top: 10rpx;
            }
        }

        .mapright {
            width: 80rpx;
            height: 80rpx;
            display: flex;
            justify-content: center;
            align-items: center;

            image {
                width: 32rpx;
                height: 32rpx;
            }
        }
    }
}
.cityModule {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100vh;
    overflow: hidden;
    z-index: 99999999;
    background-color: #fff;
}
</style>

selectCity.vue

<template>
	<aPage :footerHeight="0">	
		<!-- 页面头部 -->
		<view slot="gHeader" class="grace-header-body" style="background-color: #fff;">
			<text class="grace-header-icons grace-icons icon-back grace-block" @tap="chooseCity(false)"></text>
			<view class="grace-header-content"><view style="width:100%;text-align: center;">选择城市</view></view>
		</view>
		<!-- 页面主体 -->
		<view slot="gBody" class="grace-flex-v1" id="gBody">
			<!-- 搜索组件 -->
			<view style="padding:20rpx 40rpx; background-color:#F6F7F8;display: flex;justify-content: space-between;align-items: center;" id="hSearch">
				<graceSearch @clear="search" @inputting="search"></graceSearch>
				<view class="" style="color: #007AFF;margin-left: 20rpx;font-size: 26rpx;width: 70rpx;" @tap="chooseCity(false)">取消</view>
			</view>
			<scroll-view scroll-y="true" :scroll-into-view="showCityId" :style="{ height: mainHeight + 'px' }">
				<view class="grace-body grace-margin-top" id="pageTop">
					<view class="grace-title">当前城市 : {{ currentCity }}</view>
					<view class="grace-title">热门城市</view>
					<view class="grace-wrap" style="padding-bottom:20rpx;">
						<view class="hotcity-item" v-for="(item, index) in hotCities" :key="index" :data-cityname="item.name" :data-citycode="item.code" @tap="chooseCity">
							{{ item.name }}
						</view>
					</view>
					<block v-for="(cities, index) in cityData" :key="index">
						<view class="grace-city-AZ" :id="'grace-city-AZ-' + index">{{ index }}</view>
						<view
							class="city-item"
							:id="'grace-city-list-' + city.id"
							v-for="(city, cindex) in cities"
							:key="cindex"
							:data-cityname="city.name"
							:data-citycode="city.id"
							@tap="chooseCity"
						>
							{{ city.name }}
						</view>
					</block>
					<view class="grace-city-AZ-right">
						<view v-for="(char, index) in FristPin" :key="index" :data-char="char" @tap="changAZ">{{ char }}</view>
					</view>
				</view>
			</scroll-view>
		</view>
	</aPage>
</template>
<script>
var pinyin = new (require('../src/help/pinyin'))({checkPolyphone: false,charCase:0});
export default {
	onReady: function() {
		setTimeout(() => {
			uni.createSelectorQuery()
				.select('#gBody')
				.fields({ size: true }, res => {
					uni.createSelectorQuery()
						.select('#hSearch')
						.fields({ size: true }, res2 => {
							this.mainHeight = res.height - res2.height;
							// #ifdef H5
							this.mainHeight = res.height - res2.height - 44;
							// #endif
						})
						.exec();
				})
				.exec();
		}, 1000);
	},
	data() {
		return {
			mainHeight: 700,
			cityData: [],
			// AZ: dataObj.AZ,
			cityData:{},
			FristPin: ["A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M", "N", "P", "Q", "R", "S", "T", "W", "X", "Y", "Z"],
			currentCity: '北京市',
			hotCities: [
				{ code: 110000, name: '北京市' },
				{ code: 310000, name: '上海市' },
				{ code: 330100, name: '杭州市' },
				{ code: 610100, name: '西安市' },
				{ code: 120000, name: '天津市' },
				{ code: 340200, name: '芜湖市' }
			],
			showCityId: '',
			searchTimer: null,
			searchIndex: -1,
			amapPlugin:{}
		};
	},
	onLoad() {
		let self = this;
	},
	methods: {
		cityPinyin(cities,city){
			let self = this;
            console.log('cities',JSON.stringify(cities))
            if(cities){
                self.processing(cities,city)
            }else{
                uni.getStorage({
                    key: 'cities',
                    success: function (res) {
                        console.log(res.data);
                        if(!res.data)return;
                        cities = JSON.parse( res.data);
                        self.processing(cities,city)
                    }
                });
            }
		},
        processing(cities,city){
            let self = this;
            let cityArr = [],hotCities = [];
            for (let i = 0,len=cities.length; i < len ; i++) {
            	//遍历数组,拿到城市名称
            	let cityName = cities[i].name;
            	//取全部城市的首字母
            	let fristName = pinyin.getCamelChars(cityName).substring(0, 1);    //这里截取首字母的第一位
            	//给原json添加首字母键值对
            	cities[i].first = fristName;
            	//放入新数组
            	cityArr.push(cities[i]);
            	//判断是不是热门城市
            	if(cities[i].hot){
            		hotCities.push(cities[i])
            	}
            }
            self.hotCities = hotCities;
            		
            let cityJson = {};
            //根据首字母键值对给原数据按首字母分类
            for (let i = 0; i < self.FristPin.length; i++) {    //这里的FirstPin是一个写入了所有字母的数组,见data中
            	cityJson[self.FristPin[i]] = cityArr.filter(function (value) {
            		return value.first === self.FristPin[i];
            	})
            }
            self.cityData = cityJson;
            
            self.currentCity = city;
            console.log(self.cityData)
        },
		// 搜索
		search: function(k) {
			k = k.toLowerCase();
			if (k == '') {
				this.showCityId = 'pageTop';
				return;
			}
			if (this.searchTimer != null) {
				clearTimeout(this.searchTimer);
			}
			this.searchTimer = setTimeout(() => {
				this.searchBase(k);
			}, 500);
		},
		searchBase: function(k) {
			this.searchIndex = -1;
			
			for (var i in this.cityData) {
				for (var ii = 0; ii < this.cityData[i].length; ii++) {
					if (this.cityData[i][ii].name.indexOf(k) == 0 ) {
						this.searchIndex = this.cityData[i][ii].id;
						break;
					}
				}
				if (this.searchIndex != -1) {
					break;
				}
			}
			if (this.searchIndex != -1) {
				this.showCityId = 'grace-city-list-' + this.searchIndex;
			}
		},
		// 点击切换
		changAZ: function(e) {
			var char = e.currentTarget.dataset.char;
			uni.showToast({ title: char, icon: 'none' });
			this.showCityId = 'grace-city-AZ-' + char;
		},
		// 选择
		chooseCity: function(e) {
			let self = this;
			if(e ==false){
				// self.currentCity = false
				self.$emit('chooseCity','');
			}else{
				// 数据保存在 cityname 和 citycode
				var cityname = e.currentTarget.dataset.cityname;
				var citycode = e.currentTarget.dataset.citycode;
				// uni.showToast({
				// 	title: cityname + ' [ ' + citycode + ' ]',
				// 	icon: 'none'
				// });
				self.currentCity = cityname;
				self.$emit('chooseCity',cityname);
				self.$emit('chooseCity',self.currentCity);
			}
		},
	}
};
</script>
<style>
.grace-city-AZ {
	background: #ffffff;
	border-bottom: 1px solid #f6f7f8;
	font-weight: 700;
	line-height: 88rpx;
}
.grace-city-AZ-right {
	background: #ffffff;
	width: 50rpx;
	position: fixed;
	right: 0;
	top: 110px;
}
/* #ifdef APP-PLUS */
.grace-city-AZ-right {
	top: 260rpx; 
}
/* #endif */
/* #ifdef H5 */
.grace-city-AZ-right {
	top: 110px;
}
/* #endif */
.grace-city-AZ-right view {
	line-height: 42rpx;
	font-size: 28rpx;
	text-align: center;
}
.hotcity-item {
	width: 210rpx;
	font-size: 26rpx;
	height: 70rpx;
	line-height: 70rpx;
	border-radius: 10rpx;
	text-align: center;
	overflow: hidden;
	margin: 5rpx;
	background-color: #f6f7f8;
}
.city-item {
	line-height: 88rpx;
	height: 88rpx;
	font-size: 26rpx;
	border-bottom: 1px solid #f6f7f8;
}
</style>

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐