vue3+ts+uniapp实现小程序端input获取焦点计算上推页面距离

vue3+ts+uniapp实现小程序端input获取焦点计算上推页面距离


自我记录

1.先说我这边的需求

需求

1.给键盘同级添加一个按钮例如’下一步’ or ‘确认’ 这种按钮
2.初步想法就是获取input焦点时拿到键盘高度,并给页面的按钮设置fixed,并且bottom为键盘的高度正常逻辑是没问题的!
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

2.发现问题

发现问题:

1.当页面input在底部时(可以理解为键盘弹出时的高度会覆盖掉页面底部的input时)因为input有自动上推的属性adjustPosition,此时整个页面就会被上推至显示当前的input位置,重点是整个页面!!!
2/因为我们的按钮是根据页面去定位的,当整个页面被上推,即使按钮定位的bottom为键盘的高度也会导致按钮没有和键盘贴在一起

3.解决思路

1.查看文档是否有能获取到上推距离的属性or方法 ×
2.通过ref去获取input的target相关 ×
3.通过uni.createSelectorQuery() 获取input的target相关
3.1获取到input的底边距离屏幕顶部的距离 - 键盘高度的定位按钮的底边距离屏幕顶部的距离 = 上推距离

直接上代码

4.代码展示

<script setup lang="ts">
import { getCurrentInstance, ref } from 'vue'
//  监听键盘高度变化
const keyboardHeight = ref(0)
// 当前键盘类型
const keyboardType = ref('')
// 下一步
const nextText = ref('下一步')
const isNext = ref(false)

const onInputFocus = (event: UniHelper.InputOnFocusEvent, type: string) => {
  // 获取键盘高度
  keyboardHeight.value = Math.ceil(event.detail.height || 0)
  keyboardType.value = type

  if (['wage', 'fund', 'socialSecurity'].includes(type)) {
    nextText.value = '确定'
  } else {
    nextText.value = '下一步'
  }
  handleKeyboardOpen(type)
  // 监听键盘高度发生变化时(来短信验证码)提高按钮
  uni.onKeyboardHeightChange((res) => {
    keyboardHeight.value = Math.ceil(res.height)
    handleKeyboardOpen(type)
  })
}

// 失去焦点触发
const onInputBlur: UniHelper.InputOnBlur = () => {
  if (isNext.value) return (isNext.value = false)
   // 移除监听事件
  uni.offKeyboardHeightChange()
  keyboardHeight.value = 0
  keyboardType.value = ''
}
// 下一步触发
const onNextConfirm = (event: UniHelper.CustomEvent, type: string) => {
  isNext.value = true
  event.stopPropagation()
  if (type === 'name') {
    idCardInput.value = true
  } else if (type === 'idCard') {
    phoneInput.value = true
  } else if (['phone', 'wage', 'fund', 'socialSecurity'].includes(type)) {
    idCardInput.value = false
    phoneInput.value = false
    nameInput.value = false
    isNext.value = false
  }
}
// 主要逻辑相关!!!
//1、首先导入当前组件的实例 form 'vue'
var currentInstance = getCurrentInstance()
// 键盘弹出时计算推上去的距离
const handleKeyboardOpen = (type: string) => {
  // 使用 inputQuery 获取输入框 & 按钮位置
  //2、添加上in方法
  const inputQuery = uni.createSelectorQuery().in(currentInstance)
  const ButtonQuery = uni.createSelectorQuery().in(currentInstance)
  let rectBottom = 0
  let rectBottom2 = 0
  // 获取输入框
  inputQuery
    .select(`#${type}`)
    .boundingClientRect((rect: any) => {
      console.log(rect, 'rect')
      rectBottom = rect.bottom
    })
    .exec()
  // 获取按钮位置
  setTimeout(() => {
    ButtonQuery.select(`#next`)
      .boundingClientRect((rect: any) => {
        // rect 包含了按钮的位置信息
        rectBottom2 = rectBottom - rect.bottom
        // >0 证明 上推页面了 !=0 证明获取到按钮信息了
        if (rectBottom2 > 0 && rect.bottom !== 0) {
          keyboardHeight.value = keyboardHeight.value - rectBottom2
        }
      })
      .exec()
  })
}
</script>
<template>
 <input
  id="fund"
  class="input"
  focus
  type="digit"
  placeholder="请输入"
  placeholder-style="font-size:28rpx"
  v-model="formInfo.fundVal"
  @focus="onInputFocus($event, 'fund')"
  @blur="onInputBlur"
/>

<input
id="socialSecurity"
class="input"
type="digit"
focus
placeholder="请输入"
placeholder-style="font-size:28rpx"
v-model="formInfo.socialSecurityVal"
@focus="onInputFocus($event, 'socialSecurity')"
@blur="onInputBlur"
/>

<input
 id="wage"
  class="input"
  type="digit"
  placeholder="请输入签约工资"
  v-model="formBottomInfo.wage"
  @focus="onInputFocus($event, 'wage')"
  @blur="onInputBlur"
/>
 <!-- 下一步 -->
 <view
   id="next"
   class="nextKey"
   :style="{ bottom: keyboardHeight + 'px', display: keyboardHeight ? 'block' : 'none' }"
   @tap.stop="onNextConfirm($event, keyboardType)"
   >{{ nextText }}</view
 >
</template>
<style lang="scss" scoped>
  .nextKey {
    position: fixed;
    bottom: 0;
    right: 0;
    display: none;
    width: 140rpx;
    height: 80rpx;
    line-height: 80rpx;
    text-align: center;
    color: #fff;
    border-radius: 8rpx;
    font-size: 28rpx;
    background-color: #42b983;
  }
</style>

整理不易,如有转载请备注原文地址!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
搭建一个使用vue3+ts+vite+uniapp的微信小程序的步骤如下: 1. 首先安装最新版的Node.js和npm。 2. 安装uni-app-cli脚手架工具,命令如下: ``` npm install -g @vue/cli npm install -g @vue/cli-init npm install -g @dcloudio/uni-cli ``` 3. 创建一个uni-app项目,命令如下: ``` vue create -p dcloudio/uni-preset-vue my-project ``` 4. 进入项目目录,安装依赖包,命令如下: ``` cd my-project npm install ``` 5. 安装并配置微信小程序开发者工具,下载地址:https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html 6. 在微信小程序开发者工具中,选择导入uni-app项目,选择项目目录下的dist/dev/mp-weixin文件夹,导入后即可进行开发和调试。 7. 如果需要使用vue3和typescript,在项目中安装相关依赖包,命令如下: ``` npm install --save-dev vue@next @vue/compiler-sfc typescript ts-loader ``` 8. 在项目根目录下创建vue.config.js文件,配置如下: ``` module.exports = { chainWebpack: config => { config.module .rule('ts') .use('ts-loader') .loader('ts-loader') .tap(options => { options.appendTsSuffixTo = [/\.vue$/] return options }) } } ``` 9. 在src目录下创建shims-vue.d.ts文件,内容如下: ``` declare module "*.vue" { import { ComponentOptions } from "vue"; const component: ComponentOptions; export default component; } ``` 10. 现在你就可以使用vue3和typescript进行开发了。同时,如果需要使用vite进行开发,可以参考uni-app官方文档进行配置:https://uniapp.dcloud.io/collocation/vite 以上就是使用vue3+ts+vite+uniapp搭建微信小程序的步骤。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值