1.
<template>
<div :style="{height: curHeight + 'px'}" class="visitMaintainContainer">
<div v-if="isOpen" :style="{height: curHeight + 'px'}">
<div v-if="right.length>0">
<section class="box">
<div class="content" style="height:100%">
<div ref="left" class="left">
<ul>
<li v-for="(item, index) in left" :key="item" ref="menuList" style="font-size: 0.26rem;" :class="{current: index == currentIndex}" @click="item ? selectItem(index) : ''">
<div class="SCJ_ellipsisCls_1" :class="{current1: index == currentIndex}">
{{ item }}
</div>
</li>
</ul>
</div>
<div ref="right" class="right" style="padding-left: 0.2rem;">
<ul style="font-size:0.26rem;">
<li v-for="(item, index) in right" :key="index" class="right-item right-item-hook" style="padding: 0.3rem 0.2rem;margin-top: 0.3rem;" :style="{'height': JSON.stringify(item) !== '{}'? '' : `${curHeight -everyHeight- 99}px`,'background-color': JSON.stringify(item) !== '{}'? '#fff' :''}">
<div style="font-size:0.26rem;font-weight:550;margin-bottom:0.3rem" :class="{current2: index == currentIndex}">
{{ item.name }}
<img v-if="index == currentIndex && index !==everyIndex" src="@/assets/icon_more_red@3x.png" alt="" style="height:0.2rem;vertical-align: middle;">
</div>
<ul style="display: flex;flex-flow: row wrap;">
<li v-for="items in item.children" :key="items.name" style="width: 30%;margin-bottom: 0.2rem;" @click="goMaintainList(items)">
<div>
<img :src="items.icon" alt="" style="width: 1.3rem;height: 1.3rem;border-radius: 0.08rem;">
<div style="margin-top: 0.1rem;font-size:0.22rem">
{{ items.name }}
</div>
</div>
</li>
</ul>
</li>
</ul>
</div>
</div>
</section>
</div>
<div v-else :style="{height: curHeight + 'px'}">
<emptyComponent v-if="!isOpen" content="暂无维修分类" />
</div>
</div>
<div v-else :style="{height: curHeight + 'px'}">
<emptyComponent content="本城市暂未开通维修服务" />
</div>
</div>
</template>
2.
<script>
import { Toast } from 'vant'
import { getVisitMaintainList } from '@/api/visitMaintain/visitMaintain'
import emptyComponent from '@/components/empty'
import BScroll from 'better-scroll'
export default {
head() {
return {
title: '上门维修'
}
},
components: {
emptyComponent,
},
data() {
return {
left: [],
right: [],
listHeight: [],
scrollY: 0, //实时获取当前y轴的高度
clickEvent: false,
curHeight: 0,
isOpen: true,
everyHeight: 0,
everyIndex: 0,
}
},
computed: {
currentIndex() {
const {scrollY,listHeight} = this
return listHeight.findIndex((tops,index )=>{
if(index !== this.everyIndex) {
return scrollY >= tops && scrollY < listHeight[index + 1]
}
})
},
},
mounted() {
this.curHeight = document.documentElement.clientHeight || document.body.clientHeight
this.getVisitMaintainList()
},
methods: {
// 跳转维修服务列表页
goMaintainList(item) {
this.$router.push({
path: '/cleanPre/serverProductList',
query: {
serviceType: 3, // 上门维修
title: item.name,
service_category_id_list: item.id
}
})
},
// 获取分类列表
getVisitMaintainList() {
Toast.loading()
let regionCode = ''
if (window.jsMethord && window.jsMethord.getCityCode) {
regionCode = window.jsMethord.getCityCode()
} else {
regionCode = '610100000000'
}
getVisitMaintainList(regionCode).then((res) => {
Toast.clear()
if (res.data.code === 200) {
this.isOpen = res.data.data.is_open
const allData = res.data.data.list
this.right = allData
let noRight = [{}]
this.right = [...this.right,...noRight]
allData.forEach(element => {
this.left.push(element.name)
})
let noLeft = ['']
this.left = [...this.left,...noLeft]
this.$nextTick(() => {
this._initScroll()
this._getHeight()
})
}
})
},
_initScroll() {
//better-scroll的实现原理是监听了touchStart,touchend事件,所以阻止了默认的事件(preventDefault)
//所以在这里做点击的话,需要在初始化的时候传递属性click,派发一个点击事件
//在pc网页浏览模式下,点击事件是不会阻止的,所以可能会出现2次事件,所以为了避免2次,可以在绑定事件的时候把$event传递过去
this.lefts = new BScroll(this.$refs.left, {
click: true
})
this.rights = new BScroll(this.$refs.right, {
click: true,
probeType: 2 //探针的效果,实时获取滚动高度
})
//rights这个对象监听事件,实时获取位置pos.y
this.rights.on('scroll', (pos) => {
this.scrollY = Math.abs(Math.round(pos.y))
})
this.rights.on('scrollEnd', (pos) => {
this.scrollY = Math.abs(Math.round(pos.y))
})
},
_getHeight() {
let rightItems = this.$refs.right.getElementsByClassName('right-item-hook')
let height = 0
this.listHeight.push(height)
for (let i = 0; i < rightItems.length; i++) {
let item = rightItems[i]
// 用于解决最后一个自己新增的数据不能点击
if(i === rightItems.length-2) {
this.everyHeight = item.clientHeight
this.everyIndex = i+ 1
}
height += item.clientHeight
this.listHeight.push(height)
}
},
selectItem(index) {
this.clickEvent = true
if (!event._constructed) {
return
} else {
let rightItems = this.$refs.right.getElementsByClassName('right-item-hook')
let el = rightItems[index]
this.rights.scrollToElement(el, 400)
}
}
},
}
</script>
3.<style scoped> .visitMaintainContainer { background-color: #f6f6f6 } .content { display: flex; position: absolute; /* bottom: 100px; */ width: 100%; overflow: hidden; background: #eee; } .left { flex: 0 0 80px; width: 1.8rem; font-size: 0.3rem; } .left li { width: 100%; height: 100%; display: block; width: 1.8rem; padding: 0.3rem 0; text-align: center; } .current { color: #e72a54; font-weight: 550; background-color: #fff; height: 0.4rem; } .current1 { color: #e72a54; font-weight: 550; background-color: #fff; border-left: 0.08rem solid #e72a54; height: 0.4rem; font-size: 0.3rem; } .current2 { color: #e72a54; } .right { flex: 1; background-color: #f6f6f6; } .right-item { } .right-item li { width: 100%; text-align: center; } </style>
请求到数据格式
注:
1.由于返回的数据格式,需要区分左右双飞翼各一个数组
2.由于数组过少,最后两个滑动定位不到,需在两个数组上各新增一个对象或字符串,用于可以点到最后一个