vue脚手架中实现二级联动

html代码

<template>
  <div class="linkage">
    <div class="linkage-button" ref="linkage-button">
      <div class="linkage-button-list" ref="linkage-button-list">
        <div
          :class="
            index == ButtonListIndex
              ? 'linkage-button-item ac'
              : 'linkage-button-item'
          "
          v-for="(item, index) in ButtonList"
          :key="item.id"
          @click="FnButtonTab(index)"
        >
          {{ item.text }}
        </div>
      </div>
    </div>
    <div class="linkage-content" ref="linkage-content" @scroll="FnScroll">
      <div class="linkage-content-list">
        <div
          class="linkage-content-item"
          v-for="item in ContentList"
          :key="item.id"
          :style="{ height: `${item.height}px` }"
        >
          <div class="linkage-content-title">{{ item.text }}</div>
        </div>
      </div>
    </div>
  </div>
</template>

js代码

<script>
export default {
  name: "linkage",
  data() {
    return {
      ButtonList: [],
      ContentList: [],
      ButtonListIndex: 0,
      ScrollBys: true,
    };
  },
  methods: {
    //   左侧按钮的渲染
    FnSetButton(n) {
      for (var i = 0; i < n; i++) {
        this.ButtonList.push({
          id: `按钮${i}`,
          text: `按钮${i}`,
        });
      }
    },
    // 右侧内容的渲染
    FnSetContent(n) {
      let ContTop = 0; //第一个元素距离页面顶部的距离
      let Random = this.FnSetRandom(750, 1400);
      for (let i = 0; i < n; i++) {
        this.ContentList.push({
          height: Random,
          id: `内容${i}`,
          text: `内容${i}`,
          top: ContTop,
        });
        ContTop += Random;
      }
    },
    // 随机数
    FnSetRandom(m, n) {
      return parseInt(Math.random() * (m - n) + n);
    },
    // 点击切换左边
    FnButtonTab(index) {
      this.ScrollBys = false;
      this.ButtonListIndex = index;
      this.$refs["linkage-content"].scrollTop = this.ContentList[index].top;
    },
    // 右边滚动切换左边
    FnScroll(ev) {
      this.ContTop = ev.target.scrollTop;
      if (this.ScrollBys) {
        let n = 0;
        for (let i = 0; i < this.ContentList.length; i++) {
          if (
            this.$refs["linkage-content"].scrollTop >= this.ContentList[i].top
          ) {
            //盒子滚动的距离如果大于右边盒子里的元素距离页面顶部的距离
            n = i;
          }
        }
        this.ButtonListIndex = n;
      }
      if (this.ContTop == this.ContentList[this.ButtonListIndex].top) {
        this.ScrollBys = true;
      }
    },
  },
  mounted() {
    this.ButtonHeight =
      this.$refs["linkage-button-list"].children[0].offsetHeight;
    this.centerIndex = Math.floor(
     ( this.$refs["linkage-button"].offsetHeight / this.ButtonHeight )/2
    );
    // console.log(this.centerIndex)
  },
  created() {
    this.FnSetButton(20);
    this.FnSetContent(20);
  },
  watch: {
    ButtonListIndex(index) {
       
      if (index > this.centerIndex) {
        this.$refs["linkage-button"].scrollTop =
          (index - this.centerIndex) * this.ButtonHeight;
      }
      if (index < this.centerIndex) {
        this.$refs["linkage-button"].scrollTop = 0;
      }
    },
  },
};
</script>

css代码

<style lang="less" scoped>
body {
  margin: 0;
}
.linkage {
  width: 100vw;
  height: 100vh;
  display: flex;
  .linkage-button {
    width: 20vw;
    height: 100vh;
    background: chocolate;
    text-align: center;
    font-size: 40px;
    color: #fff;
    overflow: scroll;
    scroll-behavior: smooth;
    .linkage-button-list {
      width: 20vw;
      .linkage-button-item.ac {
        background: lightblue;
      }
      .linkage-button-item {
        width: 20vw;
        height: 10vh;
        line-height: 10vh;
      }
    }
  }
  .linkage-content {
    width: 80vw;
    height: 100vh;
    scroll-behavior: smooth;
    overflow: scroll;
    .linkage-content-list {
      .linkage-content-item {
        width: 80vw;
        height: 100vh;
        .linkage-content-title {
          height: 6vh;
          line-height: 6vh;
          width: 80vw;
          text-align: center;
          background: chartreuse;
          color: #fff;
          font-size: 30px;
        }
      }
    }
  }
}
.linkage-button::-webkit-scrollbar {
  display: none; /* Chrome Safari */
}
.linkage-content::-webkit-scrollbar {
  display: none; /* Chrome Safari */
}
</style>

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值