uni-app picker-view在滚动或者被点击后input框如果处于有焦点状态会自动弹出手机键盘

发布于 1周前 作者 eggper 来自 Uni-App

uni-app picker-view在滚动或者被点击后input框如果处于有焦点状态会自动弹出手机键盘

产品分类

uniapp/App

开发环境信息

项目 信息
PC开发环境操作系统 Windows
PC开发环境操作系统版本号 22H2
HBuilderX类型 正式
HBuilderX版本号 3.99
手机系统 Android
手机系统版本号 Android 11
手机厂商 小米
手机机型 Redmi 10A
页面类型 vue
vue版本 vue2
打包方式 云端
项目创建方式 HBuilderX

示例代码

<template>  
    <view class="container">  
        <u-popup :maskCloseAble="maskCloseAble" mode="bottom" v-model="show" height="auto" :safeAreaInsetBottom="safeAreaInsetBottom" @close="close" :z-index="10000">  
            <view class="af-select">  
                <view class="af-select__header" @touchmove.stop.prevent="">  
                    <view  
                        class="af-select__header__cancel af-select__header__btn"  
                        hover-class="af-hover-class"  
                        :hover-stay-time="150"  
                        @tap="getResult('cancel')"  
                    >  
                        取消  
                    </view>  
                    <view class="af-select__header__search">  
                        <u-search placeholder="请输入" @change="textChange" :show-action="false" v-model="keyword"></u-search>  
                    </view>  
                    <view  
                        class="af-select__header__confirm af-select__header__btn"  
                        hover-class="u-hover-class"  
                        :hover-stay-time="150"  
                        @touchmove.stop=""  
                        @tap.stop="getResult('confirm')"  
                    >  
                        确定  
                    </view>  
                </view>  
                <view class="af-select__body">  
                    <picker-view @change="columnChange" class="af-select__body__picker-view" :value="defaultSelector" v-if="show">  
                        <picker-view-column>  
                            <view class="af-select__body__picker-view__item" v-for="(item, index) in columnData" :key="index">  
                                <view class="u-line-1">{{ item.label }}</view>  
                            </view>  
                        </picker-view-column>  
                    </picker-view>  
                </view>  
            </view>  
        </u-popup>  
    </view>  
</template>  

<script>  
export default {  
    name: "af-select",  
    props: {  
        list: {  
            type: Array,  
            default: []  
        },  
        maskCloseAble: {  
            type: Boolean,  
            default: true  
        },  
        safeAreaInsetBottom: {  
            type: Boolean,  
            default: true  
        },  
        show: {  
            type: Boolean,  
            default: false  
        }  
    },  
    watch: {  
        list: {  
            handler(newVal) {  
                console.log(newVal);  
                this.list = newVal;  
                this.columnData = newVal;  
            }  
        }  
    },  
    data() {  
        return {  
            keyword: '',  
            columnData: [],  
            defaultSelector: [0]  
        }  
    },  
    methods: {  
        columnChange(e) {  
        },  
        getResult(res) {  
            console.log(this.columnData[this.defaultSelector[0]]);  
            // this.$emit('confirm', this.columnData[this.defaultSelector[0]])  
        },  
        close() {  
        },  
        textChange() {  
            this.columnData = this.list.filter(item => item.label.includes(this.keyword));  
        }  
    }  
}  
</script>  

<style lang="scss" scoped>  
.container {  
    .af-select {  
        padding: 5px;  

        &__header {  
            display: flex;  
            justify-content: space-between;  
            align-items: center;  

            &__btn {  
                margin: 0 5px;  
            }  

            &__search {  
                flex: 1;  
            }  
        }  

        &__body {  
            width: 100%;  
            height: 500rpx;  
            overflow: hidden;  
            background-color: #fff;  

            &__picker-view {  
                height: 100%;  
                box-sizing: border-box;  

                &__item {  
                    display: flex;  
                    align-items: center;  
                    justify-content: center;  
                    font-size: 32rpx;  
                    padding: 0 8rpx;  
                }  
            }  
        }  
    }  
}  
</style>

操作步骤

  1. 弹出popup,使input处于焦点状态。
  2. 收起手机键盘,滑动或点击picker-view
  3. 键盘重新弹出

预期结果

滑动或点击后键盘不弹出

实际结果

手机键盘重新弹出

bug描述

picker-view在滚动或者被点击后input框如果处于有焦点状态会自动弹出手机键盘


3 回复

可以给个完整的demo看看


解决了吗?我也遇到这个问题了

在uni-app中,当picker-view组件滚动或被点击时,如果关联的input框处于焦点状态,确实可能会触发手机键盘的弹出。这种情况通常是由于事件处理不当或组件间的交互逻辑导致的。为了解决这个问题,可以通过编程方式控制input框的焦点状态,以确保在不需要键盘的时候不会弹出。

以下是一个简单的示例代码,展示了如何在picker-view滚动时取消input框的焦点,从而避免键盘弹出:

<template>
  <view>
    <!-- picker-view组件 -->
    <picker-view :value="pickerValue" @change="onPickerChange">
      <picker-view-column>
        <view v-for="item in columns" :key="item">{{ item }}</view>
      </picker-view-column>
    </picker-view>

    <!-- input框 -->
    <input v-model="inputValue" ref="inputRef" @focus="onInputFocus" />
  </view>
</template>

<script>
export default {
  data() {
    return {
      pickerValue: [0], // 初始选中值
      columns: ['选项1', '选项2', '选项3'], // picker-view的数据源
      inputValue: '', // input框的值
    };
  },
  methods: {
    onPickerChange(e) {
      // 取消input框的焦点,防止键盘弹出
      this.$refs.inputRef.blur();
      console.log('picker值改变:', e.detail.value);
    },
    onInputFocus() {
      // input框获得焦点时的处理逻辑(如果需要)
      console.log('input框获得焦点');
    },
  },
};
</script>

<style scoped>
/* 样式可根据需要调整 */
</style>

在这个示例中,我们定义了一个picker-view组件和一个input框。当picker-view的值发生变化时,onPickerChange方法会被触发,该方法内部通过this.$refs.inputRef.blur()来取消input框的焦点,从而避免键盘弹出。

请注意,这里使用了Vue的ref属性来获取input框的引用,以便在需要时调用其blur方法。如果你使用的是其他框架或原生JavaScript,获取元素引用和调用blur方法的方式可能会有所不同,但基本原理是相同的。

通过这种方式,你可以有效地控制input框的焦点状态,避免在不需要键盘时弹出,从而提升用户体验。

回到顶部