Uniapp之键盘弹窗

适用范围

  1. 评论输入框
  2. 自定义键盘顶部工具栏
  3. 其他吸附于键盘顶部的弹框

意义

对于输入框来说,一般都包含自动抬高输入框,但是对于一些自定义窗口来说(比如输入框下添加工具栏、键盘顶部添加工具栏等),就需要自己处理弹框位置了,那么这个时候键盘弹窗就解决了复杂的处理。

示例

下面示例用于展示 keyboard-popup 使用示例,当 textarea 聚焦时,textarea 就会自动抬高到键盘上方。

html 复制代码
<template>
  <!-- 评论输入框 -->
  <!-- 注意这里需要添加adjustPosition=false属性来关闭自动上推页面 -->
  <keyboard-popup ref="replyPopup">
    	<textarea
        ref="textarea"
        v-model="content"
        placeholder="请输入内容"
        focus
        auto-focus
        maxlength="500"
        :style="{height: '160rpx'}"
        :adjustPosition="false"
        :showConfirmBar="false">
        </textarea>
  </keyboard-popup>
</template>
<script>
export default {
  data() {
    return {
      content: ''
    }
  },
  methods: {
    openPopup() {
      // 打开弹窗
      this.$refs.replyPopup.open()
    },
    openPopup() {
      // 关闭弹窗
      this.$refs.replyPopup.colse()
    }
  },
  mounted() {
    // 监听键盘高度变化,用于抬高评论框
    this.$refs.replyPopup.handleKeyboardHeightChange()
  },
  onUnload() {
    // 取消键盘高度变化监听
    this.$refs.replyPopup.offKeyboardHeightChange()
  },
}
</script>

源码

以下是 KeyboardPopup 组件的源码,可根据自己的需求加以改进。

html 复制代码
<script>
export default {
  name: 'KeyboardPopup',
  props: {
    // 是否显示底部安全距离
    showSafeBottom: {
      type: Boolean,
      default: true
    }
  },
  data() {
    return {
      showVal: false,
      keyboardHeight: 0,
      isOpen: false,
      safeAreaInsetBottom: 0
    }
  },
  methods: {
    open() {
      this.showVal = true
      this.$nextTick(() => {
        this.isOpen = true
      })
    },
    close() {
      this.isOpen = false
      this.showVal = false
    },
    onClose() {
      this.isOpen = false
      this.showVal = false
      this.$emit('close')
    },
    /**
     * 设置键盘高度,用于设置内容抬高的位置
     * @param height 高度
     */
    setKeyboardHeight(height) {
      this.keyboardHeight = height
    },
    handleKeyboardHeightChange() {
      uni.onKeyboardHeightChange(res => {
        this.keyboardHeight = res.height
      })
    },
    offKeyboardHeightChange() {
      uni.offKeyboardHeightChange()
    }
  },
  mounted() {
    // 获取底部安全距离
    if (this.showSafeBottom) {
      this.safeAreaInsetBottom = uni.getSystemInfoSync().safeAreaInsets.bottom
    }
  }
}
</script>

<template>
  <u-popup :show="showVal" @close="onClose" bgColor="transparent" :safeAreaInsetBottom="false" closeOnClickOverlay>
    <view class="content-container" :style="{bottom: keyboardHeight + 'px'}">
      <slot :isOpen="isOpen"></slot>
    </view>
    <!--  底部安全距离  -->
    <view class="safeBottom" v-if="!isOpen" :style="{height: safeAreaInsetBottom + 'px'}"></view>
  </u-popup>
</template>

<style scoped lang="scss">
.content-container {
  position: relative;
}

.safeBottom {
  width: 100%;
  background-color: #fff;
}
</style>
相关推荐
AI袋鼠帝30 分钟前
火爆全网的Seedance2.0 十万人排队,我2分钟就用上了
前端
IT_陈寒32 分钟前
React Hooks闭包陷阱:你以为的state可能早就过期了
前端·人工智能·后端
Jenlybein32 分钟前
快速了解熟悉 Vite ,即刻上手使用
前端·javascript·vite
小码哥_常32 分钟前
安卓开发避坑指南:全局异常捕获与优雅处理实战
前端
lihaozecq34 分钟前
我用 1 天的时间 vibe coding 了一个多人德州扑克游戏
前端·react.js·ai编程
momo0611735 分钟前
AI Skill是什么?
前端·ai编程
言萧凡_CookieBoty35 分钟前
用 AI 搞定用户系统:Superpowers 工程化开发教程
前端·ai编程
小小小小宇36 分钟前
Go 语言协程
前端
牛奶36 分钟前
5MB vs 4KB vs 无限大:浏览器存储谁更强?
前端·浏览器·indexeddb
牛奶38 分钟前
setTimeout设为0就马上执行?JS异步背后的秘密
前端·性能优化·promise