向上滑动呼出菜单层

向上滑动呼出菜单层,类似于高德地图主页(见下图)项目是用uniapp写的,使用uni.transition,编译成微信小程序;

入行时间不久的菜鸟,写博客只为了记录一下代码片段,以防后续遇见类似需求而浪费时间;代码还有可以优化的地方,但是我没优化,如果文档有什么写错的,欢迎评论区交流;
在这里插入图片描述
直接贴代码

<template>
  <view class="index">
    <u-navbar title="u-transition" :is-back="false"></u-navbar>
    <image
      class="mainImg"
      src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fpic1.win4000.com%2Fmobile%2F2020-05-20%2F5ec49c878b478.jpg&refer=http%3A%2F%2Fpic1.win4000.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1640914481&t=c2bfcdd374daedb8c9259716a57c30d7"
      mode="widthFix"
    />
	//在最外层用u-transition组件包起来,具体可看官方文档:"https://uniapp.dcloud.io/component/uniui/uni-transition?id=基本用法";
    <uni-transition custom-class="menu_warp" :show="show" ref="menuWarp">
      <view class="warp">
        <view
          class="bar"
          @touchmove.stop="touchMove"
          @touchend.stop="touchEnd"
          @touchstart.stop="touchStart"
        ></view>
        <input
          type="text"
          placeholder="我是一个输入框"
          @focus="focus"
          @blur="blur"
        />
        <view class="text">ドラえもん</view>
      </view>
    </uni-transition>
  </view>
</template>

<script>
export default {
  data() {
    return {
      show: true,
      windowHeight: 0,
      start: 0,
      end: 0,
    };
  },
  onLoad() {
    this.windowHeight = uni.getSystemInfoSync().windowHeight;
  },
  methods: {
    //开始触摸
    touchStart(e) {
      //记录手指触摸到屏幕的那一个的位置,计算小黑条的top值
      this.start = (e.changedTouches[0].pageY / this.windowHeight).toFixed(2);
    },
    //触摸开始并且移动
    touchMove(e) {
      this.$u.throttle(
        () => {
          //step 和 run 方法 查看uniapp官方文档:"https://uniapp.dcloud.io/component/uniui/uni-transition?id=基本用法";其实文档上写需要先初始化init,但是不init也可以使用,不知道为什么
          let top =
            (e.changedTouches[0].pageY / this.windowHeight).toFixed(2) * 100 +
            "vh";
          //top:e.changedTouches[0].pageY:手指移动的实时位置,计算后转换为滑动层的top值,单位vh;
          // console.log(top);

          if (parseInt(top) >= 80) {
            top = "80vh";
          } else if (parseInt(top) <= 60) {
            top = "60vh";
          } else {
            top = top;
          }
          this.$refs.menuWarp.step({ top: top }, { duration: 180 });
          this.$refs.menuWarp.run(() => {});
        },
        60,
        true
        //节流函数:60ms内,只触发一次,感知不大,这里用的是uview封装好的节流函数,官方文档:https://v1.uviewui.com/js/debounce.html
      );
    },
    //手指离开手机
    touchEnd(e) {
      const start = this.start * 100;
      const end =
        (e.changedTouches[0].pageY / this.windowHeight).toFixed(2) * 100;
      // console.log("start", start);
      // console.log("end", end);
      if (start > end) {
        // console.log("up");
        this.$refs.menuWarp.step({ top: "60vh" }, { duration: 180 });
        this.$refs.menuWarp.run(() => {});
      } else if (start < end) {
        // console.log("down");
        this.$refs.menuWarp.step({ top: "80vh" }, { duration: 180 });
        this.$refs.menuWarp.run(() => {});
      }
    },
    //输入框获焦
    focus() {
      this.$refs.menuWarp.step({ top: "60vh" }, { duration: 180 });
      this.$refs.menuWarp.run(() => {});
    },
    //输入框失焦
    blur() {
      this.$refs.menuWarp.step({ top: "80vh" }, { duration: 180 });
      this.$refs.menuWarp.run(() => {});
    },
  },
};
</script>

<style lang="scss">
.mainImg {
  width: 100%;
}
//要给u-transition设置fixed定位
.menu_warp {
  width: 100vw;
  position: fixed;
  top: 80vh;
  left: 0;
  .warp {
    background: lightblue;
    border-radius: 40rpx 40rpx 0 0;
    padding-bottom: 300rpx;
    .bar {
      position: relative;
      width: 100%;
      height: 40rpx;
      &::after {
        content: "";
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        width: 200rpx;
        height: 10rpx;
        border-radius: 10rpx;
        background: #111111;
      }
    }

    input {
      width: 90vw;
      height: 82rpx;
      border-radius: 20rpx;
      background: #ffffff;
      color: #111111;
      margin: 24rpx auto;
      padding-left: 12rpx;
    }
    .text {
      font: 100rpx "Ravie";
      margin-top: 160rpx;
      text-align: center;
      color: #ffffff;
    }
  }
}
</style>

永远相信美好的事情即将发生

  • 5
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 13
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值