看到很多同學在每個列表設置id去獲取,根據滾動的時候判斷那個條目的外層dom距離窗口定部最近,就顯示哪個條目的地圖信息。但我這裏利用forEach循環獲取每個列表索引值和座標。
父組件
<template>
<div>
<amap
v-if="point.length"
:width="230"
:height="230"
:point="point"
:BarFixed="BarFixed"
/>
</div>
</template>
<script>
import Amap from '@/components/public/map.vue'
export default {
components:{
Amap
},
data(){
return {
list:[], //列表
point:[], //地圖座標
BarFixed:false, //滾動時地圖添加動態class
sunHight:0 //列表高度
}
},
async asyncData(ctx){
let keyword = ctx.query.keyword
let city = ctx.store.state.geo.position.city
let {status,data:{count,pois}} = await ctx.$axios.get('/search/resultsByKeywords',{
params:{
keyword,
city
}
})
let {status:status2,data:{areas,types}} = await ctx.$axios.get('/categroy/crumbs',{
params:{
city
}
})
if(status===200&&count>0&&status2===200){
return {
list: pois.filter(item=>item.photos.length).map(item=>{
return {
type: item.type.split(';')[0],
img: item.photos[0].url,
name: item.name,
comment: Math.floor(Math.random()*10000),
rate: Number(item.biz_ext.rating),
price: Number(item.biz_ext.cost),
scene: item.tag,
tel: item.tel,
status: '可訂明日',
location: item.location,
module: item.type.split(';')[0],
address:item.address
}
}),
keyword,
areas: areas.filter(item=>item.type!=='').slice(0,5),
types: types.filter(item=>item.type!=='').slice(0,5),
point: (pois.find(item=>item.location).location||'').split(',')
}
}
},
mounted(){
//列表高度
this.$nextTick(()=>{
let itemCollection = document.querySelectorAll(".s-item");
for(let i = 0; i<itemCollection.length; i++){
this.sunHight += itemCollection[i].offsetHeight;
}
})
//監聽頁面滾動事件
window.addEventListener('scroll', this.handleScroll, true);
},
destroyed(){
// 頁面摧毀的時候要關閉監聽
window.removeEventListener('scroll', this.handleScroll)
},
methods:{
handleScroll(){
let self = this;
//頁面滾動的距離
let scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop
//地圖到頂部的距離
let mapTop = document.querySelector('.m-map').offsetTop
//默認dl元素到頂部的距離
let offsetTop = 0;
this.list.forEach((item,index)=>{
//獲取每個dl的位置
offsetTop = document.querySelectorAll(".s-item")[index].offsetTop;
//滾動當前位置時,
if(scrollTop > offsetTop && scrollTop < (offsetTop+172*item.location.length)){
self.point = item.location.split(',')
// console.log("座標",self.point)
}
})
//滾動時地圖吸頂固定位置顯示
if(scrollTop > mapTop+197 && scrollTop < self.sunHight){
self.BarFixed = true //子組件動態載入class “isFixed”
}else{
self.BarFixed = false
}
}
}
}
</script>
<style lang="scss">
@import "@/assets/css/products/index.scss";
</style>
子組件map.vue
我這裏用高德地圖,異步引入組件。
<template>
<div
:id="id"
:style="{width:width+'px',height:height+'px',margin:'34px 0 0 10px'}"
class="m-map"
:class="BarFixed==true?'isFixed':''"
></div>
</template>
<script>
export default {
props: {
BarFixed:{
type:Boolean,
default(){
return false
}
},
width:{
type:Number,
default:200
},
height:{
type:Number,
default:200
},
point:{
type:Array,
default(){
return [117.000923,36.675807]
}
}
},
data() {
return {
id:`map`,
key:'5184dfc3a9de5128108b70c4d6006f1f'
};
},
watch: {
point: function (val, old) {
this.map.setCenter(val)
this.marker.setPosition(val) //更新點標記位置
}
},
mounted() {
let self = this
self.id = `map${Math.random().toString().slice(2,4)}` //隨機生成一個數值並轉成字符串取兩位數。
//異步加載地圖
window.onLoad = function(){
let map = new AMap.Map(self.id,{
resizeEnable: true,
zoom: 11,
center: self.point
})
self.map = map
//拖動條
map.plugin("AMap.ToolBar", function() {
var toolbar = new AMap.ToolBar();
map.addControl(toolbar);
let marker = new AMap.Marker({
position: self.point,
});
self.marker = marker
marker.setMap(map)
});
}
var url = 'https://webapi.amap.com/maps?v=1.4.15&key=${self.key}&callback=onLoad';
var jsapi = document.createElement('script');
jsapi.charset = 'utf-8';
jsapi.src = url;
document.head.appendChild(jsapi);
}
};
</script>
<style lang="scss" scoped>
.isFixed{
position: fixed!important;
top:0;
margin-top:0px!important;
margin-left:10px!important;
}
</style>
完結,撒花~