vue实现左右联动面板
一般适用于分类二级数组、外卖小程序
<template>
<div>
<div class="nmc-content">
<div class="nmc-wrapper">
<div
class="left"
ref="scrollLeft"
>
<div
v-for="(item, index) in arr"
:key="index"
ref='leftBox'
@click="changeModel(index)"
:class="[current==index?'active flex-one':'common flex-one']"
>
{{item.name}}
</div>
</div>
<div
class="right"
ref="scroll"
@scroll="handleScroll"
>
<div
class="main-content"
v-for="(item, index) in arr"
:key="index"
>
<div
class="top-title"
ref="rightTit"
>{{item.name}}</div>
<div class="bottom-content">
<ul
class="bottom-ul"
v-if="item.list"
>
<li
class="bottom-item"
v-for="(item1, index1) in item.list"
:key="index1"
>
<img
src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fc-ssl.duitang.com%2Fuploads%2Fitem%2F202103%2F09%2F20210309094501_jfyix.thumb.1000_0.jpg&refer=http%3A%2F%2Fc-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1675911945&t=14dcf3ffd9b9884f4accc0941ed6f140"
alt=""
/>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
leftClickFlag: false,
arr: [
{
name: "分类1",
list: [
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
],
},
{
name: "分类2",
list: [
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
],
},
{
name: "分类3",
list: [
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
],
},
{
name: "分类4",
list: [
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
],
},
{
name: "分类5",
list: [
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
],
},
{
name: "分类6",
list: [
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
],
},
{
name: "分类7",
list: [
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
],
},
{
name: "分类8",
list: [
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
],
},
{
name: "分类9",
list: [
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
],
},
{
name: "分类10",
list: [
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
],
},
{
name: "分类11",
list: [
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
{ name: "二级" },
],
},
],
current: 0,
listHeight: [],
scrollY: 0,
};
},
mounted() {
this.$nextTick(() => {
this.getBoxHeight();
this.current = 0;
this.changeModel(0);
});
},
methods: {
getBoxHeight() {
setTimeout(() => {
let rightItems =
this.$refs.scroll.getElementsByClassName("main-content");
let height = 0;
this.listHeight.push(height);
for (let i = 0; i < rightItems.length; i++) {
let item = rightItems[i];
height += item.clientHeight;
this.listHeight.push(height);
}
this.arr.forEach((item, index) => {
this.$set(item, "distance", this.listHeight[index]);
});
}, 1000);
},
changeModel(index) {
if (index == 0) {
this.$refs.scroll.scrollTop = 0;
} else {
this.$refs.scroll.scrollTop = this.arr[index].distance;
}
this.current = index;
this.leftClickFlag = true;
},
handleScrollLeft() {
let leftHeight = this.$refs.leftBox[0].clientHeight;
let height = (this.current - 6) * leftHeight;
if (this.current > 6) {
this.$refs.scrollTop += height;
}
if (this.current <= 6) {
this.$refs.scrollTop = 0;
}
},
handleScroll() {
this.scrollY = this.$refs.scroll.scrollTop;
if (this.scrollY < this.arr[1].distance) {
this.current = 0;
} else {
for (let i = 0; i < this.listHeight.length; i++) {
let start = this.listHeight[i + 1];
let end = this.listHeight[i + 2];
if (this.scrollY >= start && this.scrollY < end) {
if (this.leftClickFlag == false) {
this.current = i + 1;
}
if (this.leftClickFlag) {
this.leftClickFlag = false;
}
this.handleScrollLeft();
return;
}
}
}
},
},
};
</script>
<style lang='scss' scoped>
.flex-one {
display: flex;
justify-content: center;
align-content: center;
}
.nmc-content {
background: #f4f5f6;
padding: 0.6rem 0 0 0;
.nmc-wrapper {
width: 100%;
height: calc(100vh - 0.6rem);
display: flex;
.left {
width: 4.5rem;
overflow-y: auto;
-webkit-overflow-scrolling: touch;
color: #333333;
&::-webkit-scrollbar {
display: none;
}
> div {
font-size: 0.7rem;
font-weight: 500;
width: 4.5rem;
height: 2.5rem;
position: relative;
.top {
position: absolute;
top: -0.5rem;
right: 0;
width: 0.5rem;
height: 0.5rem;
background: white;
}
.bottom {
position: absolute;
top: 2.5rem;
right: 0;
width: 0.5rem;
height: 0.5rem;
background: white;
}
}
.active {
background: #ffffff;
background: white;
color: #333333;
display: flex;
align-items: center;
border-radius: 0;
.line {
width: 0.15rem;
height: 0.75rem;
object-fit: cover;
margin: 0 0.5rem 0 0;
}
}
.common {
color: #666666;
line-height: 2.5rem;
}
}
.right {
background: white;
position: relative;
flex: 1;
width: 100%;
height: 100%;
background: #fff;
overflow-y: auto;
-webkit-overflow-scrolling: touch;
padding: 0.5rem;
.main-content {
position: relative;
width: 100%;
.top-title {
height: 2rem;
text-align: left;
line-height: 2rem;
font-size: 0.65rem;
font-weight: 500;
color: #333333;
}
.bottom-content {
.bottom-ul {
width: 100%;
display: flex;
flex-wrap: wrap;
.bottom-item {
width: 33.33%;
display: flex;
flex-direction: column;
align-items: center;
margin: 0 0 0.5rem 0;
position: relative;
> img:first-child {
width: 2.5rem;
height: 2.5rem;
border-radius: 0.25rem;
object-fit: cover;
box-shadow: 0rem 0.08rem 0.15rem 0.08rem
rgba(194, 146, 108, 0.1);
}
}
}
}
}
}
}
}
</style>