一、tab 名称与自定义内容对应
- el-tabs 自带的 el-tab-pane 无法进行滚动监听。需要隐藏 el-tab-pane ,并使用自定义样式替代
<section class="detail-wrap" ref="content">
<section class="trans-contener">
<div class="na-wrap">
<el-tabs
tab-position="left"
v-model="userInfoType"
@tab-click="switchUserInfo"
>
<el-tab-pane
label="Basic Info"
name="basic"
class="aad-wrap"
></el-tab-pane>
<el-tab-pane
class="aad-wrap"
v-for="(specItem, speIndex) in detailList.detailObj"
:label="formateWords(speIndex)"
:key="speIndex"
:name="speIndex"
>
</el-tab-pane>
<el-tab-pane
class="aad-wrap"
v-for="(specItem, speIndex) in detailList.detailArray"
:label="formateWords(speIndex)"
:key="speIndex"
:name="speIndex"
>
</el-tab-pane>
</el-tabs>
</div>
<section class="conter-wrap">
<section class="basic-wrap">
<div class="list-title" id="basic">Basic Info</div>
<ul class="detail-ul">
<li v-for="(item, index) in detailList.basic" :key="index">
<a class="d-title">{{ formateWords(index) }}: </a>
<a class="d-desc" v-if="editkeyList.includes(index) && user.user_type === 0">
<el-input v-model="user[edit2Model[index]]" placeholder="请输入内容"></el-input>
</a>
<a class="d-desc" v-else>{{ item }}</a>
</li>
</ul>
</section>
<section class="specific-wrap"
v-for="(specItem, speIndex) in detailList.detailObj"
>
<div class="list-title" :id="speIndex">{{ formateWords(speIndex) }}</div>
<ul class="detail-ul">
<li v-for="(item, index) in specItem" :key="index">
<a class="d-title">{{ formateWords(index) }}: </a>
<a class="d-desc">{{ item }}</a>
</li>
</ul>
</section>
<section class="specific-wrap"
v-for="(specItem, speIndex) in detailList.detailArray"
>
<div class="list-title" :id="speIndex">{{ formateWords(speIndex) }}</div>
<ul class="detail-ul">
<li v-for="(item, index) in specItem" :key="index">
<a class="d-title">{{ formateWords(index) }}: </a>
<a class="d-desc">{{ item }}</a>
</li>
</ul>
</section>
</section>
</section>
</section>
二、tab-click 事件添加滚动效果
private switchUserInfo(e: any) {
console.log("data",e)
let targetDom = this.$refs.content as any
let index = Number(e.index)
let blocks = document.querySelectorAll('.list-title') as any
let step = 40;
let currentScrollTop = targetDom.scrollTop;
let targetOffsetTop = blocks[index].offsetTop;
console.log("currentScrollTop",currentScrollTop);
console.log("targetOffsetTop",targetOffsetTop);
if(currentScrollTop > targetOffsetTop){
const smoothUp = ()=>{
if(currentScrollTop >= targetOffsetTop){
if (currentScrollTop - targetOffsetTop >= step) {
currentScrollTop -= step;
setTimeout(smoothUp,1);
} else {
currentScrollTop = targetOffsetTop-step;
}
targetDom.scrollTop = currentScrollTop;
}
}
smoothUp()
}else{
const smoothDown = ()=>{
if (currentScrollTop <= targetOffsetTop) {
if (targetOffsetTop - currentScrollTop >= step) {
currentScrollTop += step;
setTimeout(smoothDown,1);
} else {
currentScrollTop = targetOffsetTop-step;
}
targetDom.scrollTop = currentScrollTop;
}
};
smoothDown()
}
this.userInfoType = e.name
}
三、监听 scroll 事件,定位到对应的 Tab
this.$nextTick(() => {
(this.$refs.content as any).addEventListener('scroll', this.handleScroll, false)
})
private handleScroll () {
this.$nextTick(() => {
let scrollTop = (this.$refs.content as any).scrollTop
let blocks = document.querySelectorAll('.list-title') as any
blocks.forEach((item: any, index: any) => {
console.log("blocks", item.id)
if (scrollTop >= (item.offsetTop - 80)) {
this.userInfoType = item.id;
}
})
})
}
四、el-tabs 组件默认的 el-tab-pane 进行隐藏
::v-deep .el-tabs__content {
display: none;
}
五、最终效果