以 vue directive 指令举例:
首先,对每个 input 输入框绑定 window 窗口变动事件:
Vue.directive("keyboard", {
inserted: function (el) {
const $input = el.querySelector("input");
const onResize = () => {
};
const onFocus = () => {
originalHeight = window.innerHeight;
// 添加 resize 监听器
window.addEventListener('resize', onResize);
};
const onBlur = () => {
console.log('onblur')
$input.removeEventListener('focus', $input._onFocus);
window.removeEventListener('resize', $input._onResize);
}
$input.addEventListener('focus', onFocus);
$input.addEventListener('blur', onBlur)
// 存储事件处理函数用于卸载
$input._onFocus = onFocus;
$input._onResize = onResize;
},
unbind: function (el) {
const $input = el.querySelector("input");
// 移除事件监听器
$input.removeEventListener('focus', $input._onFocus);
window.removeEventListener('resize', $input._onResize);
// 清除引用
delete $input._onFocus;
delete $input._onResize;
}
});判断键盘是否弹起(当前窗口小于初始化状态),通过 el.scrollIntoView 将当前输入框自动上升,避免遮挡。
const onResize = () => {
console.log('onResize')
const newHeight = window.innerHeight;
// 判断是否是视口变小(可能是键盘弹出)
if (newHeight < originalHeight - 50) {
// 延迟一点再滚动,确保 DOM 更新完成
setTimeout(() => {
$input.scrollIntoView({ behavior: "smooth", block: "end", inline: "nearest" });
}, 50); // 可根据设备调整时间
}
};组件调用:
<van-field required v-keyboard v-model.trim="form.mobile" name="mobile" :rules="rules.mobile" maxlength="11"
:border="false" :placeholder="$t('message.mobilePlaceholder')">
<template #label>
<span class="required">{{ $t("message.mobile") }}</span>
</template>
</van-field>实际效果:
