累了 直接上 代码
记得安装 npm install --save vue-scrollto
main.js
var VueScrollTo = require('vue-scrollto')
Vue.use(VueScrollTo)
整体 代码
<template>
<div class="app-container">
<div class="navBox">
<div
v-for="(item, index) in navList "
v-scroll-to="{ el: `.${item.title+index}`,container: `#scrollBox`,offset: 0,onStart:onStart,onDone:onDone,onCancel:onCancel}"
:class="[index?'marginTopTenSix':'',selectIndex===index?'colorBlue bold':'marginRightTenSix']"
class="pointer flex align-center"
@click="changeSelectIndex(index)"
>
{{ item.title }}
<div v-show="selectIndex===index" class="blueBorder" />
</div>
</div>
<div id="scrollBox" class="scrollBox" @scroll="onScroll">
<div v-for="(item, index) in navList">
<div :id="item.title+index" class="title" :class="item.title+index">{{ item.title }}</div>
<div v-for="goods in item.detail" class="goods">
{{ goods.name }}
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'Index',
data() {
return {
selectIndex: 0,
navList: [{
title: '女装',
detail: [{
name: '女装111'
}, {
name: '女装222'
}, {
name: '女装333'
}, {
name: '女装444'
}]
}, {
title: '男装',
detail: [{
name: '男装111'
}, {
name: '男装222'
}]
}, {
title: '食品',
detail: [{
name: '食品111'
}, {
name: '食品222'
}, {
name: '食品333'
}, {
name: '食品444'
}]
}, {
title: '美妆',
detail: [{
name: '美妆111'
}, {
name: '美妆222'
}, {
name: '美妆333'
}]
}]
}
},
created() {
},
methods: {
onStart() {
this.isMore = true
},
onDone() {
this.isMore = false
},
onCancel() {
this.isMore = false
},
changeSelectIndex(e) {
this.selectIndex = e
},
// 滚动监听器
onScroll(e) {
if (this.isMore) {
return
}
// 获取所有锚点元素
const navContents = document.querySelectorAll('.title')
// 所有锚点元素的 offsetTop
const offsetTopArr = []
navContents.forEach((item, index) => {
if (index) {
offsetTopArr.push(item.offsetTop)
}
})
// 获取当前文档流的 scrollTop
const scrollTop = e.target.scrollTop
// 定义当前点亮的导航下标
let navIndex = 0
for (let n = 0; n < offsetTopArr.length; n++) {
// 那么此时导航索引就应该是 n 了
if (scrollTop + 20 >= offsetTopArr[n]) {
navIndex = n + 1
}
}
// 把下标赋值
this.selectIndex = navIndex
}
}
}
</script>
<style scoped lang="scss">
.app-container{
padding: 20px;
height: 300px;
width: 600px;
box-sizing: border-box;
overflow: auto;
display: flex;
}
.navBox{
background: #f3d1d1;
padding: 16px 0 16px 16px ;
border-radius: 8px;
.blueBorder{
width: 4px;
height: 16px;
background: #2F54EB;
border-radius: 8px;
margin-left: 12px;
margin-right: 0px;
}
.marginRightTenSix{
margin-right: 16px;
}
}
.pointer {
cursor: pointer;
}
.scrollBox{
overflow: auto;
height: 260px;
flex-grow:1;
background: #FFFFFF;
margin-left: 16px;
border-radius: 8px;
.title{
background: #bfc3cb;
height: 44px;
line-height: 44px;
padding-left: 16px;
}
.goods{
width: 100px;
height: 100px;
margin-top: 16px;
border-radius: 8px;
background: #f5dab1;
}
}
</style>