茶叶分类:右侧滚动数据,联动左侧样式

400 阅读1分钟

茶叶分类:右侧滚动数据,联动左侧样式 这个思路对于新手的我来说感觉有点难,不熟悉这种套路,等有了经验才觉得没那么难吧 好好记录笔记,方便今后回头查看

思路:

  1. 动态绑定class ,用对象形式,并结合计算属性

  2. 计算属性又结合findIndex 和 数据的比较

 要做的3步如下:      
//动态绑定:class样式
   :class="{active:index==currentIndex}"// 右侧滚动 联动左侧菜单
    // 1. 滚动右侧 获得右侧滚动距离根据 better-scroll 的 on(type, fn, context) 实现
    //    1.1 听说早在很久以前(但现在没有),是有个一个坑导致滚动无法获取距离的,
          // 解决:要在滚动事件中添加一个属性:probeType:2|3,默认是0 参考:https://better-scroll.github.io/docs-v1/doc/zh-hans/options.html#probetype
    
    this.wrapper_menu.on("scroll", (pos) => {
      //   console.log(pos);
      //   获取滚动Y的距离 并取绝对值
      this.scrollY = Math.abs(pos.y);
    });
    
    
三 //  计算属性 自己认真分析,平时学知识点 很少遇到这种情况,老师教的时候也是经验之谈吧
  computed: {
    currentIndex() {
      return this.scrollHeight.findIndex((item, index) => {
        // console.log(item, index);
        return (
          this.scrollY >= item && this.scrollY < this.scrollHeight[index + 1]
        );
      });
    },
  },
  
  
  整体代码:
  <template>
  <div class="section">
    <div class="l-menu">
      <div class="wrapper">
        <ul>
          <li
            v-for="(item,index) in menuList"
            :key="index"
            @click="clickLeftMenu(index)"
            :class="{active:index==currentIndex}"
          >{{item.title}}</li>
        </ul>
      </div>
    </div>
    <div class="r-menu">
      <div class="wrapper-menu">
        <div ref="scrolls">
          <ul
            class="recommend"
            ref="ulrecommend"
            v-for="(item,index) in recommendInfo"
            :key="index"
          >
            <li v-for="(k,i) in item" :key="i">
              <div>{{k.title}}</div>
              <ul class="Tea">
                <li v-for="(s,idxs) in k.list" :key="idxs">
                  <img :src="s.imgUrl" alt />
                  <div>{{s.title}}</div>
                </li>
              </ul>
            </li>
          </ul>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import http from "@/common/api/request.js";
// 引入插件
import BScroll from "better-scroll";
export default {
  data() {
    return {
      menuList: [],
      recommendInfo: [],
      wrapper_menu: "",
      scrollHeight: [], // 右侧滚动距离的数组(ul每个高度,在左侧点击菜单的时候用这里的距离)
      scrollY: "", // 右侧滚动的距离
    };
  },

  created() {
    this.getList();
  },
  methods: {
    async getList() {
      let res = await http.$axios({
        url: "/api/goods/list",
      });

      let menuList = [];
      let recommendInfo = [];
      //   console.log(res);
      res.forEach((i) => {
        menuList.push({
          id: i.id,
          title: i.title,
        });
        recommendInfo.push(i.data);
      });
      this.menuList = menuList;
      this.recommendInfo = recommendInfo;

      // 左侧滚动
      this.$nextTick(() => {
        new BScroll(".wrapper", {
          click: true,
          pullUpLoad: true,
          scrollbar: true,
          pullDownRefresh: true,
        });
      });

      // 右侧滚动的
      this.$nextTick(() => {
        this.wrapper_menu = new BScroll(".wrapper-menu", {
          pullUpLoad: true,
          scrollbar: true,
          pullDownRefresh: true,
        });

        // 右侧滚动的距离
        let height = 0;
        this.scrollHeight.push(height);

        // 获取右侧每一个ul的dom元素
        let uls = this.$refs.ulrecommend;
        // 装伪数组转换为真正的数组,然后获取每一个ul的dom元素的高度
        Array.from(uls).forEach((i) => {
          //   console.log(i.clientHeight);
          // 获取每个ul的高度 并累加后 添加到一个空的数组里
          height += i.clientHeight;
          this.scrollHeight.push(height);
        });

        // console.log(height);
        // console.log(uls);
        // console.log(this.scrollHeight);

        // 右侧滚动 联动左侧菜单
        // 1. 滚动右侧 获得右侧滚动距离根据 better-scroll 的 on(type, fn, context) 实现
        //    1.1 听说早在很久以前(但现在没有),是有个一个坑导致滚动无法获取距离的,
        // 解决:要在滚动事件中添加一个属性:probeType:2|3,默认是0 参考:https://better-scroll.github.io/docs-v1/doc/zh-hans/options.html#probetype
        //
        this.wrapper_menu.on("scroll", (pos) => {
          //   console.log(pos);
          //   获取滚动Y的距离 并取绝对值
          this.scrollY = Math.abs(pos.y);
        });
      });
    },

    // 点击左侧菜单导航栏,设置右侧ul的滚动距离
    clickLeftMenu(index) {
      console.log(index);
      //   获取滚动的dom元素
      //   滚动 右侧scrollHeight数组中 对应数组下标的值
      console.log(this.$refs.scrolls);
      this.wrapper_menu.scrollTo(0, -this.scrollHeight[index], 300);
    },
  },
  //  计算属性
  computed: {
    currentIndex() {
      return this.scrollHeight.findIndex((item, index) => {
        // console.log(item, index);
        return (
          this.scrollY >= item && this.scrollY < this.scrollHeight[index + 1]
        );
      });
    },
  },
};
</script>



<style lang="less" scoped>
.section {
  display: flex;
  position: fixed;
  justify-content: space-between;
  height: 100vh;
  width: 100vw;
  .l-menu {
    border-right: 1px solid #cccccc;
    ul {
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
      li {
        font-size: 0.48rem;
        margin: 0.266667rem;
      }
    }
    // ul li::before {
    //   content: "";
    //   position: absolute;
    //   display: inline-block;
    //   width: 1px;
    //   height: 20px;
    //   background-color: red;
    // }
    ul .active {
      //   position: fixed;
      padding-left: 0;
      border-left: 1px solid red;
      //   box-sizing: border-box;
    }
  }

  .r-menu {
    .wrapper-menu {
      height: 35vh;
    }
    flex: 1;
    .recommend {
      display: flex;
      flex-direction: column;
      .Tea {
        display: flex;
        flex-wrap: wrap;
        margin: 0 0.533333rem 0.533333rem;
        flex: 1;

        li {
          display: flex;
          justify-content: center;
          align-items: center;
          flex-direction: column;

          width: 2rem;
          height: 2rem;
          margin: 0.133333rem;
          div {
            font-size: 0.373333rem;
          }
          img {
            width: 1.413333rem;
            height: 1.413333rem;
          }
        }
      }
    }
    .recommend li > div {
      margin: 0.266667rem;
      font-size: 0.48rem;
      text-align: center;
    }
  }
}
</style>

滚动右边的数据 左边的菜单导航根据判断滚动的高度,自动跳到对应的菜单选项

image.png