安装: npm install vue-jsonp 然后在main.js里导入挂载: import { VueJsonp } from 'vue-jsonp' //一定要加个花括号{VueJsonp },不然会报错 Vue.use(VueJsonp)
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" } }] }); }) } } }
为什么不能直接把初始化地图的方法放在mounted生命周期里?是因为我这里用了v-show.放在mounted的话,就会报id为null,找不到’container’这个节点.
是因为mounted只加载页面的数据,而这个模态款是需要二次点击才能显示的,所以模态款里面的dom节点都没有加载.所以要用watch监听模态框如果是显示状态,就调用地图初始化的方法.
还有一点,一定要放在this.nextTick()里面,不然也会报找不到id的错误.原因是可能他先调用了初始化地图方法里面的document.getElementById('container') .而这时模态款里面的dom还没加载完,this.nextTick()就是等dom加载完再执行的意思.