适用范围
- 评论输入框
- 自定义键盘顶部工具栏
- 其他吸附于键盘顶部的弹框
意义
对于输入框来说,一般都包含自动抬高输入框,但是对于一些自定义窗口来说(比如输入框下添加工具栏、键盘顶部添加工具栏等),就需要自己处理弹框位置了,那么这个时候键盘弹窗就解决了复杂的处理。
示例
下面示例用于展示 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>