基于vue-baidu-map封装地图组件,实现可搜索功能

基于vue-baidu-map封装地图组件,实现可搜索功能

前言:在vue项目中引入vue-baidu-map,封装BaiduMap组件,实现点击搜索按钮,展开搜索栏,根据搜索信息展示结果列表。通过点击,定位到地图上。

文章目录


![在这里插入图片描述](https://www.icode9.com/i/ll/?i=20210312112848870.gif#pic_center)

基于vue-baidu-map封装地图组件,实现可搜索功能

一、按需引入vue-baidu-map

1.安装

npm install vue-baidu-map

参考文档:https://dafrok.github.io/vue-baidu-map/#/zh/index

2.按需引入

在components文件夹中新建一个BaiduMap公共组件

<template>
	<baidu-map 
		class="map" 
        ak="D15n2WFnProuzYA0gFwVrWE0y3nMhmgA" 
        :zoom="map.zoom" 
        :center="{lng: map.center.lng, lat: map.center.lat}" 
        @ready="handler" 
        :scroll-wheel-zoom="true"
     >
     	<!--比例尺控件-->
        <bm-scale anchor="BMAP_ANCHOR_TOP_RIGHT"></bm-scale>
        <!--缩放控件-->
        <bm-navigation anchor="BMAP_ANCHOR_BOTTOM_RIGHT" ></bm-navigation>
        <!--聚合动态添加的点坐标-->
        <bm-marker-clusterer :averageCenter="true">
        	<bm-marker v-for="marker of markers" :key="marker.stationId" 
            	:position="{lng: marker.lng, lat: marker.lat}" 
                @click="lookDetail(marker)"
                :icon="{url:require('../assets/img/s_ico4.png'),opts: {imageSize: {width:30,height:30}}, size:{width:30, height:30}}"
             ></bm-marker>
         </bm-marker-clusterer>
         <!--信息窗体-->
         <bm-info-window 
         	:position="{lng: infoWindow.info.lng, lat: infoWindow.info.lat}"
         	:title="infoWindow.info.stationName" 
         	:show="infoWindow.show" 
         	@close="infoWindowClose" 
         	@open="infoWindowOpen">
            	<p><span class="">快充数:</span><span class="right">{{infoWindow.info.fastChargeNum}}个</span></p>
                <p><span class="">慢充数:</span><span class="right">{{infoWindow.info.slowChargeNum}}个</span></p>
                <p><span class="">状态:</span><span class="right">{{infoWindow.info.status}}</span></p>
                <p><span class="">正在充电:</span><span class="right">{{infoWindow.info.charging}}个</span></p>
                <p><span class="left"></span><span class="right"><a class="a-info" @click="gotoReal(infoWindow.info.stationId)">详细信息</a></span></p>
          </bm-info-window>
    </baidu-map>
</template>

<script>
import BaiduMap from 'vue-baidu-map/components/map/Map.vue';
import BmScale from 'vue-baidu-map/components/controls/Scale';
import BmNavigation from 'vue-baidu-map/components/controls/Navigation';
import BmMarkerClusterer from  'vue-baidu-map/components/extra/MarkerClusterer';
import BmMarker from 'vue-baidu-map/components/overlays/Marker';
import BmInfoWindow from 'vue-baidu-map/components/overlays/InfoWindow';

export default {
	name: 'BaiduMap',
	components: {
        BaiduMap, BmScale, BmNavigation, BmMarkerClusterer, BmMarker, BmInfoWindow
    },
    ....
	methods: {
		// 地图初始化
        handler ({BMap, map}) {
            console.log(BMap, map);
            let mapStyle = {style: "midnight"}
            map.setMapStyle(mapStyle);
            this.getProPositionMap();
        },
        infoWindowClose (e) {
            this.infoWindow.show = false
        },
        infoWindowOpen (e) {
            this.infoWindow.show = true
        },
        //查看详情
        lookDetail(data, target){
            this.infoWindow.show =true;
            this.infoWindow.info=data;
            this.activeName = data.stationName;
            //为弹窗口标题添加title
            this.$nextTick(()=>{
                var win=document.querySelector(".BMap_bubble_title");
                win.title = this.activeName;
            })
            if(target=='left'){ //点击的是左侧列表项,则不需要滚动
                this.map.center={lng: data.lng, lat: data.lat};
                this.map.zoom = 15;
                return;
            }
            //滚动到指定元素位置
            this.$nextTick(()=>{
                var obj=document.querySelector(".active");
                var scrollTop=obj.offsetTop;
                this.$refs.box.scrollTop=scrollTop-180;
            })
        }        
	}
}
</script>

二、查询动态抽屉样式

1.写搜索样式栏及结果列表

提示:我在项目中已引入element-ui,所以搜索栏下拉框选择使用el-select编写。结果列表中使用了el-row布局模块进行展示。

  <!-- 左侧搜索栏 -->
                <div class="left">
                    <div class="top">
                        <div class="item fl">
                            <el-select 
                                filterable 
                                clearable 
                                v-model="districtType" 
                                placeholder="请选择行政区域" 
                                style="width: 160px;margin-left: 5px;"
                                @change="regionsChange"
                            >
                                <el-option v-for="item in districtTypeOptions" :key="item.title" :label="item.title"
                                        :value="item.title">
                                </el-option>
                            </el-select>
                        </div>
                    </div>
                    <div class="header">共{{markers.length}}个充电站</div>
                    <div class="list" :style="{height:leftHeight}">
                        <div class="list-context">
                            <div ref="box" class="list-scroll bmr-y-scroll" :style="{height:leftHeight}">
                                <div class="listItemDIV">
                                    <div class="row" v-for="marker of markers" :key="marker.stationId" @click="lookDetail(marker,'left')" :class="{active: activeName == marker.stationName}">
                                        <div class="head-title" v-text="marker.stationName" :title="marker.stationName"></div>
                                        <div class="row-content">
                                            <el-row style="margin-bottom:10px;">
                                                <el-col :span="8">
                                                    {{marker.status}}
                                                </el-col>
                                                <el-col :span="8">
                                                    <img src="../assets/img/s_ico1.png">
                                                    {{marker.fastChargeNum}}Kw
                                                </el-col>
                                                <el-col :span="8">
                                                    <img src="../assets/img/s_ico2.png">
                                                    {{marker.slowChargeNum}}A
                                                </el-col>
                                            </el-row>
                                        </div>
                                    </div>
                                </div>
                        	</div>
                        </div>
                    </div>
                </div>

2.实现一个button

<!-- 按钮图标 -->
            <div id="mapContainer" @click="drawer = true">
                <div class="btnLayer">
                    <div class="search">
                        <div class="searchInner">
                            <a href="javascript:;" class="searchBtn"><span class="icoSearch"></span></a> 
                        </div>
                    </div>
                </div>
            </div>

注意:button绑定一个@click=“drawer = true”

3.实现抽屉动效

提示:抽屉动效中同样用到了el-drawer

<el-drawer style="position:absolute; z-index:-1;" direction="ltr" :visible.sync="drawer" :with-header="false" :modal="false">
     <!--此处放2.1中写的搜索栏  --!>
</el-drawer>

export default {
	data() {
		return {
	            drawer: false,
	    }
	}
}

总结

       通过element-ui及vue-baidu-map封装一个公共map组件,需要注意css层级之间的宽高度设计。另外,此版本中百度信息窗体bm-info-window的样式和整体项目风格维和,后续还要修改其css样式。
       关于element-ui及vue-baidu-map的css样式修改,使用< style>标签时注意不要同时使用scoped。
上一篇:Uni-app父组件如何调用子组件的方法 | 父页面如何调用子页面的方法


下一篇:jquery滚动到指定元素,模仿锚点