vue better-scroll左右联动使用笔记

1、安装

cnpm install better-scroll --sava

2、使用(在弹框内使用)

HTML

<!-- 祭拜弹框 -->
    <van-popup
      :lock-scroll="false"
      class="popup_box"
      v-model="showWorshipPopup"
      position="bottom"
      :style="{ height: '55%' }"
    >
      <div class="popup_title"><span>请选择祭拜品</span></div>
      <div class="popup_content">
        <div class="left" ref="left">
          <ul class="content">
            <li
              v-for="(item, index) in left"
              :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 class="content">
            <li
              class="right-item right-item-hook"
              v-for="(item, index) in right"
              :key="index"
            >
              <h2>
                <span>{{ item.name }}</span>
              </h2>
              <ul>
                <li v-for="child in item.content" :key="child.id">
                  <div class="img_box">
                    <img :src="child.img" alt="" />
                  </div>
                  <div class="child_info">
                    <div class="info_left">
                      <h3>{{ child.name }}</h3>
                      <h4>价格:<span>{{ child.price?child.price/100+'元':'免费' }}</span></h4>
                    </div>
                    <div class="info_right" @click="gongfeng(child)">
                      <span>立即供奉</span>
                    </div>
                  </div>
                </li>
              </ul>
            </li>
          </ul>
        </div>
      </div>
    </van-popup>

 JS

import BScroll from "better-scroll";
export default {
  data() {
    return {
      showWorshipPopup: false, //祭拜底部弹框
      left: [],
      right: [],
      listHeight: [],
      scrollY: 0, //实时获取当前y轴的高度
      clickEvent: false,
      lefts: null,
      rights: null,
    }
  },
   watch: {
    showWorshipPopup(newValue, oldValue) {
      if (newValue) {
        this.$nextTick(() => {
          this._initScroll();
          this._getHeight();
        });
      }
    },
  },
  computed: {
    //
    currentIndex() {
      const index = this.listHeight.findIndex((item, index) => {
        return (
          this.scrollY >= this.listHeight[index] &&
          this.scrollY < this.listHeight[index + 1]
        );
      });
      return index > 0 ? index : 0;
    },
  },
   methods: {
    //初始化betterscroll
    _initScroll() {
      //better-scroll的实现原理是监听了touchStart,touchend事件,所以阻止了默认的事件(preventDefault)
      //所以在这里做点击的话,需要在初始化的时候传递属性click,派发一个点击事件
      //在pc网页浏览模式下,点击事件是不会阻止的,所以可能会出现2次事件,所以为了避免2次,可以在绑定事件的时候把$event传递过去
      if (!this.lefts) {
        this.lefts = new BScroll(this.$refs.left, {
          click: true,
        });
      } else {
        this.lefts.refresh();
      }
      if (!this.rights) {
        this.rights = new BScroll(this.$refs.right, {
          click: true,
          probeType: 3, //探针的效果,实时获取滚动高度
        });
      } else {
        this.rights.refresh();
      }
      //rights这个对象监听事件,实时获取位置pos.y
      this.rights.on("scroll", (pos) => {
        this.scrollY = Math.abs(Math.round(pos.y));
      });
    },
    //获取滚动区域高度数组
    _getHeight() {
      let rightItems = this.$refs.right.getElementsByClassName(
        "right-item-hook"
      );
      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);
      }
      console.log(this.listHeight, "98989");
    },
    //点击左侧分类
    selectItem(index, event) {
      this.clickEvent = true;
      //在better-scroll的派发事件的event和普通浏览器的点击事件event有个属性区别_constructed
      //浏览器原生点击事件没有_constructed所以当时浏览器监听到该属性的时候return掉
      if (!event._constructed) {
        return;
      } else {
        let rightItems = this.$refs.right.getElementsByClassName(
          "right-item-hook"
        );
        let el = rightItems[index];
        this.rights.scrollToElement(el, 300);
      }
    },
  }

}

CSS 

//祭拜弹框
  .popup_box {
    background: #f1f1f1;
    display: flex;
    flex-direction: column;
    .popup_title {
      width: 100%;
      height: 0.44rem;
      background: $defaultColor;
      display: flex;
      align-items: center;
      color: #fff;
      padding-left: 0.15rem;
      font-size: 16px;
    }
    .popup_content {
      flex: 1;
      // margin-bottom: 0.12rem;
      display: flex;
      justify-content: space-between;
      overflow: hidden;
      .left {
        flex: 0 0 1rem;
        background-color: #fff;
        margin-right: 0.1rem;
        li {
          display: flex;
          align-items: center;
          justify-content: center;
          width: 100%;
          height: 0.5rem;
          position: relative;
        }
        .current {
          background: #f1f1f1;
          color: $defaultColor;
        }
        .current::after {
          content: "";
          width: 4px;
          height: 15px;
          border-radius: 5px 0 0 5px;
          position: absolute;
          background-color: $defaultColor;
          top: 0;
          right: 0px;
          bottom: 0;
          margin: auto;
        }
      }

      .right {
        flex: 1;

        .right-item {
          margin-top: 0.1rem;
          background-color: #fff;
          h2 {
            display: flex;
            align-items: center;
            padding-left: 0.15rem;
            height: 0.5rem;
            border-bottom: 1px solid rgba(0, 0, 0, 0.1);
            span {
              margin-left: 0.05rem;
            }
          }
          h2::before {
            content: "";
            width: 6px;
            height: 6px;
            border-radius: 50%;
            background: $defaultColor;
          }
          li {
            width: 100%;
            padding: 0.15rem 0.1rem 0.15rem 0.15rem;
            display: flex;
            align-items: center;
            border-bottom: 1px solid rgba(0, 0, 0, 0.1);
            .img_box {
              width: 0.6rem;
              height: 0.6rem;
              background: #efefef;
              border-radius: 0.03rem;
              padding: 0.1rem;
              margin-right: 0.08rem;
              img {
                width: 100%;
                height: 100%;
              }
            }
            .child_info {
              flex: 1;
              display: flex;
              align-items: center;
              justify-content: space-between;
              .info_left {
                h3 {
                  font-size: 14px;
                  line-height: 0.2rem;
                  margin-bottom: 0.05rem;
                }
                h4 {
                  display: flex;
                  align-items: center;
                  font-size: 12px;
                  color: $lightBlack;
                  span {
                    color: $defaultColor;
                  }
                }
              }
              .info_right {
                width: 0.72rem;
                height: 0.3rem;
                color: #fff;
                display: flex;
                align-items: center;
                justify-content: center;
                background: $defaultColor;
                border-radius: 0.06rem;
              }
            }
          }
        }
      }
    }
    .popup_bottom {
      width: 100%;
      background: #ffff;
      height: 0.44rem;
      display: flex;
      padding: 0 0.12rem;
      align-items: center;
      justify-content: space-between;
      .bottom_left {
        display: flex;
        align-items: center;
        span {
          margin-right: 0.08rem;
        }
        /deep/ .van-switch {
          width: 0.5rem;
          height: 0.25rem;
          border-radius: 0.25rem;
          .van-switch__node {
            width: 0.24rem;
            height: 0.24rem;
          }
        }
        /deep/ .van-switch--on .van-switch__node {
          transform: translateX(0.25rem);
        }
      }
    }
  }

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【为什么前端都要学习Vue】 这几年Vue.js成为前端框架中最火的一个。越来越多的网站前端开始采用Vue.js开发。是开源世界华人的骄傲,作者是我国的尤雨溪大神。相对于其他前端框架,Vue 更容易上手!正因为它简单易学,很多前端开发工程师可以很快掌握并且应用到实际开发中。如果说你想用最短的时间来学习一个框架,快速上手项目,Vue是不二之选。 【学员收益】 1)大部分学员想要学习Vue,但是无奈缺少一个好老师,董老师将手把手带领你学习,让你彻底掌握Vue框架。 2)课程将会长期维护,内容更超值,本课程基于最新的版本进行讲解,并且老师会更新升级到3.0稳定版本。 3)学完该课程后不仅能学到Vue的设计和开发技能,还能培养市场思维、用户思维、设计思维,并能够利用掌握的技术开发Vue项目,获取额外的收益。 【课程收获】 1、从基础知识到项目实战,内容涵盖Vue各个层面的知识和技巧2、学习曲线平缓,前端新人也可以看得懂3、贴近企业项目,按照企业级代码标准和工程开发的流程进行讲解4、让你能够独立开发高颜值的项目 5、项目涉及14大功能组件,从基础组件到业务组件,一站式全掌握 【项目效果】 本课程打造的是高颜值的美团外卖项目。不仅界面美观,而且涉及到了众多页面。多说无益,请大家扫码查看课程效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值