对于通过向下滚动到底部,然后网络请求加载下一个类别的数据这个功能已经实现了的,需要的朋友私聊我,目前这里是写死的
----------
<template>
<section class="box">
<div class="head">联动数据</div>
<div class="content">
<div class="left" ref="left">
<ul>
<li
v-for="(item, index) in leftList"
:key="item"
:class="{ current: currentIndex == index }"
@click="selectItem(index, $event)"
>
<span class="left-item">{{ item }}</span>
</li>
</ul>
</div>
<div class="right" ref="right">
<ul>
<li
class="right-item right-item-hook"
v-for="item in rightList"
:key="item.name"
>
<div v-if="item.content[0]" class="tip">{{ item.name }}</div>
<ul>
<li
v-for="num in item.content"
:key="num.name"
@click="clickHandle(num)"
>
<div>{{ item.name + num }}</div>
</li>
</ul>
</li>
</ul>
</div>
</div>
</section>
</template>
<script>
import { computed, onMounted, reactive, ref } from 'vue';
// BScroll中文文档 https://www.mianshigee.com/tutorial/better-scroll/1.md
import BScroll from 'better-scroll';
export default {
name: 'betterScroll',
setup() {
let left = ref(null); // 左边 列表盒子
let right = ref(null); // 右边 列表盒子
let leftList = ref(['a', 'b', 'c', 'd', 'e', 'f']);
let rightList = reactive([
{
name: 'a',
content: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']
},
{
name: 'b',
content: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']
},
{
name: 'c',
content: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']
},
{
name: 'd',
content: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']
},
{
name: 'e',
content: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']
},
{
name: 'f',
content: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']
}
]);
let listHeight = ref([]); // 右边数据高度集合
let scrollY = ref(0); // 滚动距离
let rights = ref(null); // 滚动 事件源
const _initScroll = () => {
// 给左边列表绑定点击事件 BScroll会默认覆盖浏览器默认的事件 得手动添加click=true
new BScroll(left.value, {
click: true
});
rights.value = new BScroll(right.value, {
click: true,
probeType: 3 //探针的效果,实时获取滚动高度
});
//rights这个对象监听事件,实时获取位置pos.y
rights.value.on('scroll', (pos) => {
scrollY.value = Math.abs(Math.round(pos.y));
});
};
// 右边成员高度集合
const _getHeight = () => {
listHeight.value.splice(0, listHeight.value.length); //清空数组
// 右边结构 li>ul>li 第一层li对应左边每个类型
// 获取每个类型li元素实际高度
let rightItems = right.value.getElementsByClassName('right-item-hook');
let height = 0;
// 设置第一项为0, 当scrollY.value = 0 默认展示第一条
listHeight.value.push(height);
for (let i = 0; i < rightItems.length; i++) {
let item = rightItems[i];
// 一个个累加左边对应右边li的高度
height += item.clientHeight;
listHeight.value.push(height);
}
// window.console.log(listHeight.value, rightItems, '222');
};
// 点击事件
const selectItem = (index, event) => {
//在better-scroll的派发事件的event和普通浏览器的点击事件event有个属性区别_constructed
//浏览器原生点击事件没有_constructed所以当时浏览器监听到该属性的时候return掉
if (!event._constructed) {
return;
} else {
let rightItems = right.value.getElementsByClassName('right-item-hook');
let el = rightItems[index];
// 定位右边到对应的数据
rights.value.scrollToElement(el, 0);
}
};
// 给左边对应添加样式
const currentIndex = computed(() => {
// 循环listHeight高度
for (let i = 0; i < listHeight.value.length; i++) {
let height = listHeight.value[i];
let height2 = listHeight.value[i + 1];
// 当height2不存在的时候,或者落在height和height2之间的时候,直接返回当前索引
// >=height,是因为一开始scrollY.value =0,height=0
if (!height2 || (scrollY.value >= height && scrollY.value < height2)) {
return i;
}
// listHeight.value 最后一个高度等于右边所有数据内容高度总和
// right.value.clientHeight 右边可视高度
if (
listHeight.value[listHeight.value.length - 1] -
right.value.clientHeight <=
scrollY.value
) {
// // 左边条数比右边数据高度集合少一条,因为listHeight第一项是默认为0,滚动top默认为0 所以要减2
return listHeight.value.length - 2;
}
}
//如果listHeight.value没有的话,就返回0
return 0;
});
const clickHandle = (val) => {
alert(val);
};
onMounted(() => {
window.console.log();
_initScroll();
_getHeight();
});
return {
left,
right,
leftList,
rightList,
listHeight,
scrollY,
selectItem,
currentIndex,
clickHandle
};
},
components: {}
};
</script>
<style scoped lang="scss">
.head {
height: 100px;
width: 100%;
font-size: 32px;
line-height: 100px;
background: rgb(235, 163, 213);
}
.content {
display: flex;
position: absolute;
height: 1200px;
width: 100%;
overflow: hidden;
background: #eee;
}
.left {
flex: 0 0 80px;
width: 80px;
background-color: #f3f5f7;
}
.left li {
width: 100%;
height: 100%;
}
.current {
background-color: red;
transition: 0.5s linear;
}
.left-item {
display: block;
width: 100%;
height: 100px;
line-height: 100px;
text-align: center;
border-bottom: 1px solid #ccc;
}
.right {
flex: 1;
}
.tip {
text-align: left;
height: 50px;
font-size: 32px;
width: 100px;
line-height: 50px;
background: #ccc;
}
.right-item li {
width: 100%;
height: 143px;
line-height: 100px;
text-align: center;
border-bottom: 1px solid rgb(10, 134, 235);
box-sizing: border-box;
}
</style>