• vue-amap安装和使用


    之前分享了异步加载高德地图api的用法,现在记录一下vue-amap的用法。

    vue-amap 是饿了么开源的一套基于 Vue 2.0 和高德地图的地图组件。 数据状态与地图状态单向绑定,开发者无需关心地图的具体操作。

    官方文档:https://elemefe.github.io/vue-amap/#/zh-cn/introduction/install

    步骤如下:

    1.npm 安装

    npm install vue-amap --save

    如果是CDN方式,目前可通过unpkg.com/vue-amap获取最新版本的资源。

    <script src="https://unpkg.com/vue-amap/dist/index.js"></script>

    2.使用实例

    实例需求描述:搜索并选择地址,选中后地图定位到该地址,并获取经纬度自动填入下方的输入框中。

    注:实例中使用的框架是ElementUI,其表单组件使用比较方便。

    实现步骤:

    (1)安装后在main.js中设置以下内容:

    import VueAMap from "vue-amap";
    Vue.use(VueAMap);
    // 初始化vue-amap
    VueAMap.initAMapApiLoader({
      key: "your key",
      plugin: ["AMap.Autocomplete", "AMap.Geocoder", "AMap.Geolocation"],
      v: "1.4.15",
      uiVersion: "1.1"
    });

    (2)定义地图搜索组件 base/mapSearch/baseMapSearch.vue

    <template>
      <div>
        <div class="search-box">
          <el-input
            v-model="searchKey"
            type="search"
            id="search"
            placeholder="请输入详细地址"
          ></el-input>
          <!--<button @click="searchByHand">搜索</button>-->
          <div class="tip-box" id="searchTip"></div>
        </div>
        <!--
          amap-manager: 地图管理对象
          vid:地图容器节点的ID
          zooms: 地图显示的缩放级别范围,在PC上,默认范围[3,18],取值范围[3-18];在移动设备上,默认范围[3-19],取值范围[3-19]
          center: 地图中心点坐标值
          plugin:地图使用的插件
          events: 事件
        -->
        <div class="amap-box">
          <el-amap
            :amap-manager="amapManager"
            :vid="'amap-vue'"
            :zoom="zoom"
            :plugin="plugin"
            :center="center"
            :events="events"
          >
            <!-- 标记 -->
            <el-amap-marker
              v-for="(marker, index) in markers"
              :position="marker"
              :key="index"
            ></el-amap-marker>
          </el-amap>
        </div>
      </div>
    </template>
    <script>
    import { AMapManager, lazyAMapApiLoaderInstance } from "vue-amap";
    let amapManager = new AMapManager();
    export default {
      props: ["city", "value", "longitude", "latitude", "isEdit"],
      data() {
        let self = this;
        return {
          address: null,
          searchKey: "",
          amapManager,
          markers: [],
          searchOption: {
            city: this.city ? this.city : "全国",
            citylimit: true
          },
          center: [121.329402, 31.228667],
          zoom: 17,
          lng: 0,
          lat: 0,
          loaded: false,
          events: {
            init() {
              lazyAMapApiLoaderInstance.load().then(() => {
                self.initSearch();
              });
            },
            // 点击获取地址的数据
            click(e) {
              self.markers = [];
              let { lng, lat } = e.lnglat;
              self.lng = lng;
              self.lat = lat;
              self.center = [lng, lat];
              self.markers.push([lng, lat]);
              // 这里通过高德 SDK 完成。
              let geocoder = new AMap.Geocoder({
                radius: 1000,
                extensions: "all"
              });
              geocoder.getAddress([lng, lat], function(status, result) {
                if (status === "complete" && result.info === "OK") {
                  if (result && result.regeocode) {
                    self.address = result.regeocode.formattedAddress;
                    self.searchKey = result.regeocode.formattedAddress;
                    self.$emit("updateLocation", lng, lat, self.searchKey);
                    self.$nextTick();
                  }
                }
              });
            }
          },
          // 一些工具插件
          plugin: [
            {
              // 定位
              pName: "Geolocation",
              events: {
                init(o) {
                  // o是高德地图定位插件实例
                  o.getCurrentPosition((status, result) => {
                    if (result && result.position) {
                      if (self.isEdit) {
                        // 设置经度
                        self.lng = self.longitude;
                        // 设置维度
                        self.lat = self.latitude;
                        // 设置坐标
                        self.center = [self.longitude, self.latitude];
                        self.markers.push([self.longitude, self.latitude]);
                      } else {
                        // 设置经度
                        self.lng = result.position.lng;
                        // 设置维度
                        self.lat = result.position.lat;
                        // 设置坐标
                        self.center = [self.lng, self.lat];
                        self.markers.push([self.lng, self.lat]);
                      }
                      // load
                      self.loaded = true;
                      // 页面渲染好后
                      self.$nextTick();
                    }
                  });
                }
              }
            }
          ]
        };
      },
      created() {
        if (this.value) {
          this.searchKey = this.value;
          this.address = this.value;
        }
        if (this.longitude && this.latitude) {
          this.lng = this.longitude;
          this.lat = this.latitude;
          this.center = [this.longitude, this.latitude];
          this.markers.push([this.longitude, this.latitude]);
        }
      },
      methods: {
        // 选择地址后自动定位到当前地址附近
        updateAddress(value, longitude, latitude) {
          this.searchKey = value;
          this.address = value;
          this.lng = longitude;
          this.lat = latitude;
          this.center = [longitude, latitude];
          this.markers.push([longitude, latitude]);
        },
        initSearch() {
          let vm = this;
          let map = this.amapManager.getMap();
          AMapUI.loadUI(["misc/PoiPicker"], function(PoiPicker) {
            let poiPicker = new PoiPicker({
              input: "search",
              placeSearchOptions: {
                map: map,
                pageSize: 10
              },
              suggestContainer: "searchTip",
              searchResultsContainer: "searchTip"
            });
            vm.poiPicker = poiPicker;
            // 监听poi选中信息
            poiPicker.on("poiPicked", function(poiResult) {
              let source = poiResult.source;
              let poi = poiResult.item;
              if (source !== "search") {
                poiPicker.searchByKeyword(poi.name);
              } else {
                poiPicker.clearSearchResults();
                vm.markers = [];
                let lng = poi.location.lng;
                let lat = poi.location.lat;
                let address = poi.name; // poi.cityname + poi.adname + poi.name
                vm.center = [lng, lat];
                vm.markers.push([lng, lat]);
                vm.lng = lng;
                vm.lat = lat;
                vm.address = address;
                vm.searchKey = address;
                vm.$emit("updateLocation", lng, lat, vm.searchKey);
              }
            });
          });
        },
        searchByHand() {
          if (this.searchKey !== "" && this.poiPicker) {
            this.poiPicker.searchByKeyword(this.searchKey);
          }
        }
      }
    };
    </script>
    <style lang="stylus">
    .search-box {
      margin-top: 6px;
      width: 100%;
    }
    .search-box input {
      padding: 0 15px;
      width: 100%;
      height: 32px;
      line-height: 32px;
      color: #606266;
      border: 1px solid #dcdfe6;
      border-radius: 4px;
    }
    .search-box input:focus {
      border-color: #409eff;
      outline: 0;
    }
    .search-box input::-webkit-input-placeholder {
      color: #c0c4cc;
    }
    .tip-box {
      width: 100%;
      max-height:280px;
      position: absolute;
      top: 72px;
      z-index: 10000;
      overflow-y: auto;
      background-color: #fff;
    }
    </style>
    <style>
    .amap-ui-poi-picker-sugg,
    .amap_lib_placeSearch {
      border: 1px solid #eee;
      border-radius: 4px;
    }
    .amap-box {
      height: 200px;
    }
    </style>

    这里样式使用了stylus,可自行转换其他样式。

    (3)在组件中使用地图搜索组件,这里以弹窗为例

    <template>
      <el-dialog
        :title="title"
        :visible.sync="visible"
        :before-close="handleClose"
        width="600px"
        append-to-body
        :close-on-click-modal="false"
        :close-on-press-escape="false"
      >
        <div class="form-info">
          <el-form
            :model="form"
            ref="form"
            :rules="rules"
            size="small"
            label-width="110px"
          >
            <el-form-item label="选择地址" prop="address">
              <base-map-search
                ref="mapSearch"
                :city="form.city"
                :value="form.address"
                :longitude="form.addLon"
                :latitude="form.addLat"
                :isEdit="isEdit"
                @updateLocation="updateLocation"
              />
            </el-form-item>
            <el-row>
              <el-col :span="12">
                <el-form-item prop="addLon" label="经度">
                  <el-input
                    v-model.number="form.addLon"
                    :maxlength="15"
                    placeholder="请输入经度"
                  ></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="12" class="right-label-form-item">
                <el-form-item prop="addLat" label="纬度">
                  <el-input
                    v-model.number="form.addLat"
                    :maxlength="15"
                    placeholder="请输入纬度"
                  ></el-input>
                </el-form-item>
              </el-col>
            </el-row>
          </el-form>
        </div>
      </el-dialog>
    </template>
    <script>
    import BaseMapSearch from "../base/mapSearch/baseMapSearch";
    export default {
        props: ["visible", "isEdit", "detail"],
        components: {
          BaseMapSearch
        },
        data() {
            return {
                title: "添加地址",
                form: {
                    address: "",
                    addLon: "",
                    addLat: ""
                },
                rules: {
                    areas: [
                      {
                        required: true,
                        validator: areasRule,
                        trigger: ["blur", "change"]
                      }
                    ],
                    addLat: [
                      {
                        required: true,
                        validator: numberRule,
                        trigger: ["blur", "change"]
                      }
                    ],
                    addLon: [
                      {
                        required: true,
                        validator: numberRule,
                        trigger: ["blur", "change"]
                      }
                    ],
                }
            };
        },
        created() {
          if (this.isEdit) {
            this.initForm();
          }
        },
        methods: {
            // 初始化表单
            initForm() {
              this.title = "修改地址";
              if (this.detail) {
                this.form = { ...this.detail };
              }
            },
            // 地图搜索选址
            updateLocation(lng, lat, address) {
              this.form.addLon = lng;
              this.form.addLat = lat;
              this.form.address = address;
            },
            handleClose() {
              this.$emit("update:visible", false);
            }
        }
    };
    </script>

    (4)这时,如果项目中使用了ESlint,会报AMap、AMapUI未定义的错误,我们需要在.eslintrc.js文件中定义globals属性:

    module.exports = {
        // ...
        globals: {
          AMap: false,
          AMapUI: false
        }
    };

    这样就写好了,效果如图:

  • 相关阅读:
    Solaris 11 system package 安装与更新(如:assembler)
    JS实现页面内跳转
    使用Eclipse进行嵌入式软件开发
    Eclipse下C++标准库报错::mbstate_t has not been declared
    嵌入式ARM开发环境搭建
    CCS内存数据转成图片
    RESET
    Android 圆角研究
    Java 重写必须满足的条件
    android 社会化分享集成
  • 原文地址:https://www.cnblogs.com/yeqrblog/p/13631391.html
Copyright © 2020-2023  润新知