UniApp 键盘抬起
概述
在移动端开发中,键盘的弹出和收起会影响页面布局,特别是在聊天、评论等需要输入的场景中。UniApp 提供了多种方式来监听键盘状态变化,本文基于实际项目中的聊天页面代码,详细介绍如何实现键盘监听功能。
核心事件
@keyboardheightchange
这是 UniApp 中最重要的键盘监听事件,当键盘高度发生变化时会触发。
javascript
// 事件对象结构
{
detail: {
height: number, // 键盘高度(像素)
duration: number // 动画持续时间(毫秒)
}
}
完整实现代码
模板部分 (Template)
vue
<template>
<view class="chat-page page-content">
<!-- 消息列表 -->
<scroll-view class="w-common chat-page-messages page-content-body" scroll-y scroll-with-animation> 测试键盘 </scroll-view>
<!-- 输入框 -->
<view class="chat-page-input" :style="style">
<input class="input-field" v-model="inputText" placeholder="请输入消息..." :adjust-position="false" @confirm="sendMessage" @keyboardheightchange="handleKeyboardheightchange" />
<view class="send-btn" :class="{disabled: !inputText.trim()}" @click="sendMessage"> 发送 </view>
</view>
</view>
</template>
脚本部分 (Script)
javascript
<script setup>
import { ref, computed } from 'vue';
import lodash from 'lodash';
// 响应式数据
const inputText = ref('');
const keyboardHeight = ref(0);
// 计算样式 - 根据键盘高度动态调整底部内边距
const style = computed(() => {
const flag = keyboardHeight.value > 0;
const height = flag
? `calc(20rpx + ${keyboardHeight.value}px)`
: `calc(env(safe-area-inset-bottom))`;
return `padding-bottom: ${height};`;
});
// 发送消息的核心逻辑
const sendMessage = async () => {
if (!inputText.value.trim()) return;
// 这里添加发送消息的业务逻辑
console.log('发送消息:', inputText.value);
// 清空输入框
inputText.value = '';
// 隐藏键盘
uni.hideKeyboard();
};
// 键盘高度变化处理函数(使用防抖优化)
const handleKeyboardheightchange = lodash.debounce((e) => {
console.log('键盘高度变化:', e.detail);
keyboardHeight.value = e.detail.height;
// 可以在这里添加其他业务逻辑
// 比如:滚动到底部、调整页面布局等
}, 100);
</script>
样式部分 (Style)
scss
<style lang="scss" scoped>
.chat-page {
height: 100vh;
display: flex;
flex-direction: column;
background-color: #f5f5f5;
&-messages {
flex: 1;
overflow-y: auto;
}
// 输入框区域
&-input {
background-color: #fff;
padding: 20rpx 32rpx env(safe-area-inset-bottom);
border-top: 1rpx solid #e5e5e5;
display: flex;
align-items: center;
position: relative;
transition: padding-bottom 0.3s ease-out; // 添加过渡动画
// 输入框
.input-field {
flex: 1;
background-color: #f8f8f8;
border-radius: 20rpx;
padding: 20rpx 32rpx;
font-size: 32rpx;
border: none;
outline: none;
margin-right: 20rpx;
&::placeholder {
color: #999;
}
}
// 发送按钮
.send-btn {
min-width: 120rpx;
height: 80rpx;
background-color: #95ec69;
border-radius: 40rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 28rpx;
color: #fff;
font-weight: 500;
padding: 0 24rpx;
transition: all 0.2s ease;
&:active {
background-color: #7dd85a;
transform: scale(0.98);
}
&.disabled {
background-color: #e5e5e5;
color: #999;
cursor: not-allowed;
}
}
}
}
</style>
关键配置说明
1. input 组件配置
vue
<input :adjust-position="false" // 关键:禁用自动调整位置 @keyboardheightchange="handleKeyboardheightchange" />
重要提示 :必须设置 :adjust-position="false"
,否则键盘弹出时页面会自动调整,影响我们的自定义监听逻辑。
2. 布局说明
重要说明 :本实现使用的是 flex 布局 ,通过 display: flex
和 flex-direction: column
来实现页面结构:
scss
.chat-page {
height: 100vh;
display: flex; // 使用flex布局
flex-direction: column; // 垂直方向排列
}
- 消息列表区域:
flex: 1
占据剩余空间 - 输入框区域:固定高度,通过动态
padding-bottom
适配键盘
3. 防抖处理
javascript
const handleKeyboardheightchange = lodash.debounce((e) => {
keyboardHeight.value = e.detail.height;
}, 100);
使用防抖函数避免键盘高度频繁变化时的性能问题。
4. 动态样式计算
javascript
const style = computed(() => {
const flag = keyboardHeight.value > 0;
const height = flag ? `calc(20rpx + ${keyboardHeight.value}px)` : `calc(env(safe-area-inset-bottom))`;
return `padding-bottom: ${height};`;
});
根据键盘高度动态计算底部内边距,确保输入框不被键盘遮挡。
兼容性说明
平台 | 支持程度 | 备注 |
---|---|---|
微信小程序 | ✅ 完全支持 | 推荐使用 |
H5 | ⚠️ 部分支持 | 部分浏览器可能不支持 |
App | ✅ 完全支持 | iOS/Android 都支持 |
支付宝小程序 | ✅ 完全支持 | |
百度小程序 | ✅ 完全支持 |
最佳实践
1. 性能优化
- 使用防抖函数避免频繁触发
- 合理设置过渡动画时间
- 避免在键盘事件中进行复杂计算
2. 用户体验
- 添加平滑的过渡动画
- 考虑安全区域适配
- 处理键盘弹出时的页面滚动
3. 兼容性处理
- 在不同平台进行测试
- 提供降级方案
- 处理异常情况
常见问题
Q: 为什么设置 adjust-position="false"
后页面布局异常?
A: 这是正常的,需要手动处理键盘高度变化,通过监听 keyboardheightchange
事件来调整布局。
Q: 键盘高度获取不准确怎么办?
A: 可以使用 uni.getKeyboardHeight()
API 获取准确的键盘高度,并在 keyboardheightchange
事件中进行校正。
Q: 如何优化键盘弹出时的性能?
A: 使用防抖函数、避免在事件处理中进行 DOM 操作、合理设置 CSS 过渡时间。
总结
通过监听 @keyboardheightchange
事件,我们可以精确控制键盘弹出时的页面布局,提供更好的用户体验。关键是要设置 adjust-position="false"
并正确处理键盘高度变化,结合防抖优化和动态样式计算,实现流畅的键盘交互效果。
