JSONP方式实现基于腾讯地图的地图搜索组件开发

1.vue项目中index.html引入

 <script charset="utf-8" src="https://map.qq.com/api/js?v=2.exp&key=申请的key值"></script>

2.map.vue

<template>
  <div>
    <div class="inputDiv">
      <input type="text"
             v-bind="$attrs"
             v-on="inputListeners"
             ref='input'
             autocomplete="off"
             name="address_detail"
             placeholder="请输入地址信息"
             :value="value"
             class="input_style">
      <div :class="options1.length>0?'showDiv':''">
        <div v-for="(item,index) in options1 " :key="index" @click="selectAddress(item)">
          <span >{{item.title}}</span>
        </div>
      </div>
       <!--图标-->
      <div class="visitorType-right" flex="cross:center main:center">
         <Icons :size="17" style="color:#A6B1BF;" type="ic-location"/>
      </div>
    </div>
    <div id="container" style="width:100%;height:140px;margin:0 auto"></div>
  </div>

</template>

<script>
 //接口地址具体参考 https://lbs.qq.com/webservice_v1/guide-suggestion.html
  var searchService, geocoder, map, markersArray = [];
  import Icons from '@/components/icons'
  const jsonp = require('jsonp');
  // import qq from "qqmap"

  export default {
    data() {
      return {
        options1: [],
        temp:false
      }
    },
    props: {
      // 编辑回显数据
      value: {
        type: String,
        default: ''
      }

    },
    //如果你不希望组件的根元素继承 attribute,你可以在组件的选项中设置 inheritAttrs: false
    inheritAttrs: false,
    //这尤其适合配合实例的 $attrs 属性使用,该属性包含了传递给一个组件的 attribute 名和 attribute 值
    computed: {
      inputListeners: function () {
        var vm = this
        // `Object.assign` 将所有的对象合并为一个新对象
        return Object.assign({},
          // 我们从父级添加所有的监听器
          this.$listeners,
          // 然后我们添加自定义监听器,
          // 或覆写一些监听器的行为
          {
            // 这里确保组件配合 `v-model` 的工作
            blur: function (event) {
              if(vm.temp){
                vm.$emit('changeValue', '')
              }
              setTimeout(() => {
                vm.options1 = []
              }, 500)
            },
            // 这里确保组件配合 `v-model` 的工作
            input: function (event) {
              vm.$emit('changeValue', event.target.value)
              vm.debouncedGetAnswer(event.target.value)
            }
          }
        )
      }
    },
    components: {
      Input, Button, Select, Option,Icons
    },
    mounted() {
      this.init();
      this.debouncedGetAnswer = this.$_.debounce(this.remoteMethod1, 500, false)
    },
    methods: {
      selectAddress(item) {
        this.temp=false
        this.$emit('changeValue', item.title)

        // this.$emit('setValue', item)
        this.options1 = []
        this.codeLatLng(item)
      },
      remoteMethod1(value) {
        if (!!value) {
          this.temp=true
          jsonp(`https://apis.map.qq.com/ws/place/v1/suggestion/?keyword=${value}&key=申请的key值&output=jsonp`,null,(err, res) => {
            if (err) {

            } else {
              this.options1=res.data
            }
          })
        } else {
          this.options1 = [];
        }
      },
      remoteMethod(value) {
         jsonp(`https://apis.map.qq.com/ws/place/v1/suggestion/?keyword=${value}&key=申请的key值&output=jsonp`,null,(err, res) => {
           if (err) {
             console.error("errerrerrerr",err.message);
           } else {
             this.codeLatLng(res.data[0])
           }
         })
      },
      codeLatLng(item) {
        var lat = item.location.lat;
        var lng = item.location.lng;
        var latLng = new qq.maps.LatLng(lat, lng);
        //调用信息窗口
        var info = new qq.maps.InfoWindow({map: map});
        //清楚标记
        if (markersArray.length>0) {
          console.log("markersArray",markersArray)
          for (let i in markersArray) {
            markersArray[i].setMap(null);
          }
        }
        //调用获取位置方法
        geocoder.getAddress(latLng);
      },
      init() {
        var center = new qq.maps.LatLng(39.916527, 116.397128);
        map = new qq.maps.Map(document.getElementById('container'), {
          center: center,
          zoom: 13
        });
        var info = new qq.maps.InfoWindow({map: map});
        geocoder = new qq.maps.Geocoder({
          complete: function (result) {
            console.log("result",result)
            map.setCenter(result.detail.location);
            var marker = new qq.maps.Marker({
              map: map,
              position: result.detail.location
            });
            markersArray.push(marker);
            //添加监听事件 当标记被点击了  设置图层
            qq.maps.event.addListener(marker, 'click', function () {
              info.open();
              info.setContent('<div>' +
                result.detail.address + '</div>');
              info.setPosition(result.detail.location);
            });
          }
        });
        if(this.value){
          this.temp=false
          this.remoteMethod(this.value)
          // geocoder.getLocation(this.value)
          // var latLng = new qq.maps.LatLng(this.add.lat, this.add.lng);
          // //调用信息窗口
          // var info = new qq.maps.InfoWindow({map: map});
          // //调用获取位置方法
          // geocoder.getAddress(latLng);
        }

      },
    }
  }
</script>
<style scoped>
  input{
    outline: none;
    transition: border 0.2s ease-in-out, background 0.2s ease-in-out, box-shadow 0.2s ease-in-out, -webkit-box-shadow 0.2s ease-in-out;
  }
  .inputDiv{
    position: relative;
  }
  .inputDiv>div{
    width: 100%;
    position: absolute;
    top: 40px;
    text-align: center;
    background: #f7f9fc;
    z-index: 100000;
  }
  .inputDiv>div>div{
    height: 30px;
    line-height:30px;
    cursor: pointer;
  }
  .inputDiv>div>div:hover{
    color: dodgerblue;
  }
  #container {
    width: 100%;
    height: 140px;
  }

  .input_style {
    color: #4d5259;
    width: 100%;
    height: 40px;
    padding-left: 5px;
    border-radius: 3px;
    border: none;
    background: #f4f6fa;
    border: 1px solid #f4f6fa !important;
    margin-bottom: 9px;
  }
  .input_style:hover{
  border: 1px solid #9cbcf9 !important;
}
  .nopass .input_style{
    background: #fdeded;
    border-color: #FFB2B2 !important;
  }
  .nopass .input_style:hover{
    border-color:#e25f5f !important;
  }
   .tangram-suggestion-main{
    z-index: 20000;
  }
  /deep/ .smnoprint{
    display: none!important;
  }
   .inputDiv .visitorType-right {
    width: 30px;
    position: absolute;
    right: 0px;
    top: 4px;
    background: bottom;
  }
  .showDiv{
    transition: all 1s ease-in .1s;
  }
</style>

3.引用map.vue

<template>
  <Map v-if="temp" v-on:blur.native="onBlur"   @changeValidate="changeValidateForm"    @changeValue="changeValueMap"  v-model="address"></Map>
</template>

<script>
  import Map from './maplist'

  export default {
    name: "mapInput",
    components: {
      Map
    },
    data(){
      return {
        temp:false,
        address:'芜湖镜湖万达广场',
      }
    },
    mounted(){
      setTimeout(()=>{
        this.temp=true
      },500)
    },
    methods: {
      changeValidateForm() {
        console.log("changeValidateForm")
      },
      changeValueMap(value){
        this.address=value
      }
    }
  }
</script>

<style scoped>

</style>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值