前言:这个利用vue.js+elementUI进行开发。我真的是找遍百度都找不到几篇关于vue使用腾讯地图开发的文章。使用百度地图的文章很多。恰巧我这个项目他规定要用腾讯地图。不然我也想用百度地图,直接考前辈门的代码就能用了。这个整的真的脑壳痛,从腾讯地图开发文档看着一个一个怼,然后怼一个报一个错…对了搜索地址的框用的是element的el-autocomplete

腾讯地图官方文档:https://lbs.qq.com/webDemoCenter/glAPI/glMap/mapCenter
问题一 : 如果存在跨域问题,可以用vue-jsonp来解决。elementui自定安装

安装: npm install vue-jsonp
然后在main.js里导入挂载:
import { VueJsonp } from 'vue-jsonp' //一定要加个花括号{VueJsonp },不然会报错
Vue.use(VueJsonp)

1. vue不同普通的html一样直接引入<script></script>就行,而是在vue.js里面要把<script src="https://map.qq.com/api/gljs?v=1.exp&key=你创建的key"></script> 引入public目录里的index.html文件里

在这里插入图片描述

2.然后就能在你的.vue文件里使用了。如果你创建地图的div不含v-show,v-if,等等。就可以直接获取到id节点。因为我这里创建的地图是在一个模态款里的。所以下面会用到监听事件watch。上代码…

1.页面代码

<el-button @click="modelMsg=true"></el-button>
<!-- 添加模态款 -->
 <el-dialog :title="title" :visible.sync="modelMsg">
    <div class="msgDiv">
	<el-autocomplete style="width: 80%;margin-right: 10px;" class="inline-input" v-model="address" :fetch-suggestions="watchInput" placeholder="请输入内容" :trigger-on-focus="false" @select="handleSelect"></el-autocomplete>
      <div id="container"></div>
    </div>
</el-dialog>

2.data数据

export default {
    data() {
      return {
      	modelMsg:false, //显示模态框
      	address: "",  //输入的地址
      	mapList: [], //用来存搜索到的所有地址
 	mapVal: '' //创建的地图,赋值用
      }
    },
    watch: {
    //监听模态框是否显示,显示就执行初始化地图方法
      modelMsg(newVal, oldVal) {
        console.log(newVal)
        if (newVal == true) {
          this.initMap(23.12908, 113.26436)
        }
      }
    },
    methods: {
    	//框框选中一条触发函数,并再执行初始化地图的方法
      handleSelect(item) {
        this.initMap(item.location.lat, item.location.lng)
      },
      //监听输入框输入状态,这个方法是实时搜索,并显示地点关键词
      //queryString是传入的关键词,cb是回调函数,就是把获取到的列表赋值到下拉框里
      //这个是element的el-autocomplete官方文档是这么传的,我也不知道为啥.
      watchInput(queryString, cb) {
        this.mapList = []
        console.log(queryString)
        const KEY = "5B2BZ-O6UHW-ASRRZ-OE6AU-2L7VF-HKFR4";
        let url = "https://apis.map.qq.com/ws/place/v1/suggestion"
        let keyword = queryString //传入的关键词
        this.$jsonp(url, {
          key: KEY,
          region: "全国",
          keyword: keyword,
          output: "jsonp"
        }).then(res => {
          let opt = []
          res.data.forEach(res => {
            let opt1 = {
              "value": res.title + "-" + res.address,
              "location": res.location
            }
            opt.push(opt1)
          })
          this.mapList = opt
          console.log(this.mapList)
          // 调用 callback 返回建议列表的数据
          cb(this.mapList);
        }).catch(err => {
          console.log(err)
        })
      },
      //初始化地图
      initMap(lat, lng) {
        //如果地图存在,就销毁,下面会重新创建一个
        if (this.mapVal) {
          this.mapVal.destroy()
        }
        //定义地图中心点坐标
        //this.$nextTick是等Dom加载完再执行
        this.$nextTick(() => {
          var center = new window.TMap.LatLng(lat, lng)
          //定义map变量,调用 TMap.Map() 构造函数创建地图
         this.mapVal = new TMap.Map(document.getElementById('container'), {
            center: center, //设置地图中心点坐标
            zoom: 17.2, //设置地图缩放级别
            pitch: 43.5, //设置俯仰角
            rotation: 45, //设置地图旋转角度
            viewMode: '2D',
            mapStyleId: "style1" //个性化样式
          });
          //初始化marker
          var marker = new TMap.MultiMarker({
            id: "marker-layer", //图层id
            map: this.mapVal,
            styles: { //点标注的相关样式
              "marker": new TMap.MarkerStyle({
                "width": 25,
                "height": 35,
                "anchor": {
                  x: 16,
                  y: 32
                },
                "src": "https://mapapi.qq.com/web/lbs/javascriptGL/demo/img/markerDefault.png"
              })
            },
            geometries: [{ //点标注数据数组
              "id": "demo",
              "styleId": "marker",
              "position": new TMap.LatLng(lat, lng),
              "properties": {
                "title": "marker"
              }
            }]
          });
        })
      }
    }
 }

效果图

在这里插入图片描述
在这里插入图片描述

注意:如果报id null啥的就是那个document.getElementById(‘container’)没找到.

为什么不能直接把初始化地图的方法放在mounted生命周期里?是因为我这里用了v-show.放在mounted的话,就会报id为null,找不到’container’这个节点.

是因为mounted只加载页面的数据,而这个模态款是需要二次点击才能显示的,所以模态款里面的dom节点都没有加载.所以要用watch监听模态框如果是显示状态,就调用地图初始化的方法.

还有一点,一定要放在this.nextTick()里面,不然也会报找不到id的错误.原因是可能他先调用了初始化地图方法里面的document.getElementById('container') .而这时模态款里面的dom还没加载完,this.nextTick()就是等dom加载完再执行的意思.

Logo

前往低代码交流专区

更多推荐