看到很多同学在每个列表设置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>
完结,撒花~