In the whole network scarce, complete chain home map house search implementation (A) chapter, we have achieved the map in the map house search initialization, regional bubbles and regional boundary display and interaction, so in this paper we need to do is the map around the house source display and interaction.
The project has been online, I am experiencing ~
Display of surrounding properties
The display logic of surrounding houses is roughly as follows:
-
The user clicks a regional bubble, and the map zooming level increases (at this time, the map’s zoom is updated to the critical value ZOOMBOUNDARY of the disappearance of regional bubbles + 1, this.zoom = ZOOMBOUNDARY + 1). At this time, surrounding house bubbles and dataToast prompt appear, while regional bubbles and regional boundaries disappear
-
When the user enlarges the map, when the zoom level is greater than the critical value, the same as above; When the value is less than the critical value, regional bubbles appear, and the total number of surrounding houses and surrounding houses disappear
-
When the scale level of the map is greater than the critical value, the user drags the map and updates the surrounding houses after dragging (that is, send get request, parameters need to be well communicated with the students at the back end, here I query by the coordinates of the current center point of the map).
After analyzing the scene displayed by the surrounding houses, we divided it into three steps to realize it step by step.
Step1 — The user clicks on a region bubble
AroundOverlay first we need to abstract a surrounding house component — aroundOverlay. This component is similar to the zoneOverlay, with a few changes in style and content.
<template>
<bm-overlay
ref="customOverlay"
class="around"
pane="labelPane"
@draw="draw"> <div> <! - the contents of the div can adjust themselves - > < p > {{text. The title}} < / p > < p > {{math.h ceil (10000). The text initialPrice /}} m < / p > < / div > < / bm - overlay > </template> <script>export default {
props: ['text'.'position'.'active'],
watch: {
position: {
handler () {
this.$refs.customOverlay.reload()
},
deep: true} }, methods: { draw ({el, BMap, map}) { const {lng, lat} = this.position const pixel = map.pointToOverlayPixel(new BMap.Point(lng, El.style. left = Pixel.x -61 +'px'
el.style.top = pixel.y - 18 + 'px'
}
}
}
</script>
<style lang="stylus" scoped>
.around
overflow: hidden
width: 122px
height: 36px
padding: 5px
box-shadow: 0 0 1px #bbbBackground - color: rgba (58126255,0.9) color:#fff
text-align: center
position: absolute
font-size: 12px
line-height: 13px
border-radius: 5px
box-sizing: border-box
div
display: flex
flex-wrap: wrap
overflow: hidden
text-overflow: ellipsis
white-space: nowrap
justify-content: space-between
p
overflow: hidden
text-overflow: ellipsis
white-space: nowrap
width: 100%
text-align: center
</style>
Copy the code
And dataToast, a nearby listing notification component
<template>
<div class="toast">
<slot></slot>
</div>
</template>
<script>
export default {
name: 'dataToast'
}
</script>
<style lang="scss"scoped> .toast{ position: fixed; left: 0; right: 0; bottom: 20px; width: 340px; height: 26px; margin: auto; padding: 3px 10px; Background - color: rgba (0, 0, 7); color:#fff;
font-size: 12px;
line-height: 20px;
box-sizing: border-box;
}
</style>
Copy the code
AroundOverlay using aroundOverlay in the map container
<baidu-map id="bm-view" class="bm-view" :center="center" :zoom="zoom" :scroll-wheel-zoom="true" :inertial-dragging="true" @ready="handler" @zoomend="syncCenterAndZoom">
<bm-boundary v-if="showBoundary" :name="zoneBoundary" :strokeWeight="2" strokeColor="blue" fillColor="skyblue" :fillOpacity="0.4"></bm-boundary>
<div v-if="showZone">
<zone-overlay
v-for="(item, index) in zoneGeoPoints" :key="index"
:position="{lng: item.lng, lat: item.lat}"
:text="item"
@mouseover.native="selectZone(item, index)"
@mouseleave.native="cancelZone"
@click.native="selZone(item, index)">
</zone-overlay>
</div>
<div v-if=! "" showZone">
<around-overlay
v-for="(item, index) in aroundGeoPoints" :key="index"
:position="{lng: item.lng, lat: item.lat}"
:text="item">
</around-overlay>
</div>
</baidu-map>
Copy the code
The user clicks a regional bubble, which is the corresponding selZine event, at which time the regional bubble and regional boundary disappear, while the surrounding houses appear. Set the map zoom level ZOOM to the critical value ZOOMBOUNDARY plus 1, and set the longitude and latitude center of the central point of the map. Finally, send a request to obtain the data of surrounding houses.
selZone (item, index) {
this.showZone = false
this.$set(this.center, 'lng', item.lng)
this.$set(this.center, 'lat', item.lat)
this.zoneBoundary = ' '
this.showBoundary = falseThis.zoom = ZOOMBOUNDARY + 1 // updateHouseList(item.lng, item.lat)}Copy the code
For the dataToast component, which I put outside the map container, I need to put the map-related part in a component (which I abstracted into the searchMap component) and put it in a container div with the rest of the content.
<div> <searchMap></searchMap> <! -- Store the zoom level in vuEX in the updateHouseList method above, disappear and display in sync with the surrounding house components, aroundCnt corresponds to the total number of surrounding houses --> <dataToast V-if ="this.$store.state.showAround > ZOOMBOUNDARY "> there are {{aroundCnt}} houses in the view, drag the map to see more ~ </dataToast> </div>Copy the code
SearchMap components
<div> <! <baidu-map></baidu-map> </div>Copy the code
Step2 — The user scales the map
In this process, we need to update the zoom level of the bidirectional binding map, and obtain the current longitude and latitude, and then compare zoom and critical ZOOMBOUNDARY to display and hide the bubbles of surrounding houses, and make the following modifications to @zoomend=”syncCenterAndZoom”
SyncCenterAndZoom (e) {this.zoom = e.targe.getzoom () // Update zoomif (this.zoom > ZOOMBOUNDARY) {
this.showZone = falseConst {LNG, lat} = e.targe.getCenter () this.updateHouselist (LNG, lat)} const {LNG, lat} = e.targe.getCenter () this.updateHouselist (LNG, lat)}else {
this.showZone = true}}Copy the code
Step3 — the user moves the map
This process requires bidirectional binding of the map’s current latitude and longitude and updating of surrounding properties based on the latitude and longitude
<baidu-map id="bm-view" class="bm-view" :center="center" :zoom="zoom" :scroll-wheel-zoom="true" :inertial-dragging="true" @ready="handler" @zoomend="syncCenterAndZoom" @moveend="syncCenterAndZoom_"></baidu-map>
Copy the code
@moveEnd =”syncCenterAndZoom_” means that syncCenterAndZoom_ is triggered at the end of the map move. In this method, we bidirectional the current binding latitude and longitude
syncCenterAndZoom_ (e) {
const zoom = e.target.getZoom()
if(zoom > ZOOMBOUNDARY) {const {LNG, lat} = e.target.getCenter() this.updateHouselist (LNG, Lat)}}Copy the code
Interaction of surrounding houses
CSS: hover pseudo class
As with the area bubble, the bubble highlights when the mouse slides into a nearby house and recovers when the mouse slides out. Since the bubble’s OnMouseover and Onmouseleave have no easing effect, change the HOVER artifact with CSS to modify the Stylus with aroundOverlay
.around
transition: background-color .15s ease-in-out /* 缓动效果,可自己调整 */
overflow: hidden
width: 122px
height: 36px
padding: 5px
box-shadow: 0 0 1px #bbbBackground - color: rgba (58126255,0.9) color:#ffftext-align: center position: absolute font-size: 12px line-height: 13px border-radius: 5px box-sizing: Hover z-index: 1; border-box &:hover z-index: 1; background-color: rgba(240,655,52,.9) color:#fffdiv display: flex flex-wrap: wrap overflow: hidden text-overflow: ellipsis white-space: nowrap justify-content: space-between p overflow: hidden text-overflow: ellipsis white-space: nowrap width: 100% text-align: */.around. Active z-index: 1 background-color: rgba(240,65,52,.9) color: rgba(240,65,52,.9)#fff
Copy the code
Bubble hover z-index is 1 in order to make the highlighted bubble will not be covered by other bubbles, because of the reason of the cascading context, so just set z-index to 1, if you do not know the cascading context, you can go to see Zhang Xinxu teacher’s in-depth understanding of CSS cascading context and cascading order
Mouse click event @click.native
We want a nearby property bubble to be highlighted not only when the mouse slides over it, but also when the mouse clicks on it, using @click.native (native is a modifier that makes a component look like a normal HTML tag) to dynamically bind a class name and make the following changes
<div v-if=! "" showZone && this.$store.state.toggleAround">
<around-overlay
v-for="(item, index) in aroundGeoPoints" :key="index"
v-show=! "" item.isShow"
:class="curAround === item.id? 'active':''"
:position="{lng: item.lng, lat: item.lat}"
:text="item"
@click.native="selAround(item, index)">
</around-overlay>
</div>
selAround (item, index) {
this.curAround = item.id
}
Copy the code
So I’ve got a little bit of a loophole here, because I started by dynamically binding the class name to index,
:class="curAround === index? 'active':''"
selAround (item, index) {
this.curAround = index
}
Copy the code
AroundGeoPoints: aroundGeoPoints: aroundGeoPoints: aroundGeoPoints: aroundGeoPoints: aroundGeoPoints: aroundGeoPoints: aroundGeoPoints: aroundGeoPoints: aroundGeoPoints: aroundGeoPoints Because its subscript is changed to 8, the class name is bound to the element ID (fetched from behind the scenes) instead, because the element ID is unique.
Listing Detail bubble — detailOverlay
Finally, there is the Listing Detail bubble, which acts like a card that presents the listing information, the abstract detailOverlay component
<template>
<bm-overlay
ref="customOverlay"
class="detail"
pane="labelPane"
@draw="draw">
<slot></slot>
</bm-overlay>
</template>
<script>
export default {
props: ['text'.'position'.'active'],
watch: {
position: {
handler () {
this.$refs.customOverlay.reload()
},
deep: true
}
},
methods: {
draw ({el, BMap, map}) {
const {lng, lat} = this.position
const pixel = map.pointToOverlayPixel(new BMap.Point(lng, lat))
el.style.left = pixel.x - 200 + 'px'
el.style.top = pixel.y - 180 + 'px'}}} </script> <style lang="stylus" scoped>
.detail
z-index: 9
transition: background-color .15s ease-in-out
width: 400px
height: 140px
padding: 20px
box-shadow: 0 0 10px #bbb
background-color: #fff
color: #fff
text-align: center
position: absolute
font-size: 12px
line-height: 13px
border-radius: 5px
box-sizing: border-box
div
display: flex
flex-wrap: wrap
overflow: hidden
text-overflow: ellipsis
white-space: nowrap
justify-content: space-between
p
overflow: hidden
text-overflow: ellipsis
white-space: nowrap
width: 100%
text-align: center
&:after
content: ' '
display: block
position: absolute
left: 50%
bottom: -20px
width: 0
height: 0
margin-left: -10px
border: 10px solid transparent
border-top-color: #fff
</style>
Copy the code
Used in Bidu-map
<baidu-map>
<div v-if="toggleDetail">
<detail-overlay
:detailGeo="detailGeo"
:position="{lng: detailGeo.lng, lat: detailGeo.lat}"> <! -- Info-wrapper contents need to be replaced by themselves, just for reference --> <div class="info-wrapper" v-if="toggleDetail">
<div class="img">
<img :src="detailGeo.pic_url" alt="Housing Picture">
</div>
<div class="info">
<h4 class="title">{{detailGeo.title}}</h4>
<div class="price"> < div > < p > the current price < / p > < p > {{parseInt (detailGeo. CurrentPrice / 100) / 100}} m < / p > < / div > < div > < p > court evaluating price < / p > <p>{{parseInt(detailGeo. ConsultPrice / 100) / 100}} 0000 </p> </div> <div> <p> Market appraisal </p> <p>{{parseInt(detailGeo. MarketPrice / 100) / 100}} < / p > < / div > < / div > < / div > < / div > < / detail - overlay > < / div > < / baidu - map >Copy the code
AroundOverlay add onMouseOver and OnMouseleave to the aroundOverlay component, the details bubble will appear when mouse is in the house bubble and disappear when mouse is out
<around-overlay
v-for="(item, index) in aroundGeoPoints" :key="index"
v-show=! "" item.isShow"
:class="curAround === item.id? 'active':''"
:position="{lng: item.lng, lat: item.lat}"
:text="item"
@click.native="selAround(item, index)"
@mouseover.native="showCurInfo(item, index)"
@mouseleave.native="hideCurInfo"> </around-overlay> // now I do an overlay, deBounce is a function showCurInfo (item, index) { this.infoPromise = new Promise(resolve => { deBounce(() => { this.detailGeo = item this.toggleDetail =true
resolve()
})
})
return this.infoPromise
},
hideCurInfo () {
this.infoPromise.then(() => {
this.toggleDetail = false})}Copy the code
Now we have realized the display and interaction of regional bubbles, regional boundaries, surrounding houses and their details, and hints of the number of surrounding houses. The results are as follows