vue3结合vant手写一个隐藏式菜单

利用van-popup组件写一个隐藏式菜单,先获取元素的长度,然后监听滚动条,利用元素下标值,计算高度,就能定位到理想位置

    <!-- 菜单 -->
    <div class="menus-box">
      <img
        class="menus"
        src="../../../public/nav.png"
        @click="data.openMenus = true"
        v-if="!data.openMenus && !data.type"
      />
      <van-popup v-model:show="data.openMenus" position="right" :style="{ width: '50%', height: '100%' }">
        <div class="choose-box">
          <div class="choose-head">
            <van-image
              round
              width="5rem"
              height="5rem"
              fit="cover"
              src="https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg"
            />
            <div class="logo-name">标题名字</div>
          </div>
          <van-cell-group v-for="(item, index) in data.indexList1" :key="index">
            <van-cell :title="item" icon="location-o" is-link @click="btn(index)" />
          </van-cell-group>
        </div>
      </van-popup>
    </div>
let scrollTop = ref(0)
const myRef = ref(HTMLElement)
const header = ref(HTMLElement)

onMounted(() => {
  getWindowResize()
  window.addEventListener("resize", getWindowResize)
  handleScroll()
})
onBeforeUnmount(() => {
  window.removeEventListener("scroll", () => {})
  window.removeEventListener("resize", () => {})
})

const handleScroll = () => {
  window.addEventListener("scroll", () => {
    scrollTop.value = window.scrollY
  })
}
const btn = e => {
  data.openMenus = false
  document.body.scrollTop = header.value.clientHeight + (myRef.value[0].clientHeight + 18.39 - e) * e
  document.documentElement.scrollTop = header.value.clientHeight + (myRef.value[0].clientHeight + 18.39 - e) * e
}

注意:van-popup组件侧拉要设置width跟height,否则不生效,根本弹不出来;离开页面的时候,要记得销毁监听removeEventListener

其他:

监听滚动条的位置

let oldScrollTop = ref(0) // 记录上一次滚动结束后的滚动距离
let scrollFixedStatus = ref(true)
watch(
  () => scrollTop.value,
  (newValue, oldValue) => {
    setTimeout(() => {
      if (newValue === window.scrollY) {
        // 延时执行后当newValue等于window.scrollY,代表滚动结束
        // console.log("滚动结束", scrollTop.value)
        oldScrollTop = newValue // 每次滚动结束后都要给oldScrollTop赋值
        // scrollFixedStatus.value = true;
      }
    }, 20) // 必须使用延时器,否则每次newValue和window.scrollY都相等,无法判断,20ms刚好大于watch的侦听周期,故延时20ms
    if (oldScrollTop.value === oldValue) {
      scrollFixedStatus.value = false
      // 每次滚动开始时oldScrollTop与oldValue相等
      // console.log("滚动开始", scrollTop.value)
    }
  }
)

获取屏幕尺寸

// 屏幕宽度
const windowWidth = ref(0)
// 屏幕高度
const windowHeight = ref(0)
// 获取屏幕尺寸
const getWindowResize = function () {
  windowWidth.value = window.innerWidth
  windowHeight.value = window.innerHeight
  data.type = windowWidth.value < 750 ? false : true
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值