uni-app 小程序表单校验错误自动滚动到错误位置

前言

  • 表单校验错误时,自动滚动到第一个错误的位置,以便用户快速定位到错误的表单项,可提升用户体验
  • 以下是基于uni-ui组件实现的方案

效果展示

使用

1、在main.ts中引入FormPlugin插件

ts 复制代码
import { createSSRApp } from 'vue';
import App from './App.vue';
import { FormPlugin } from './plugin/form';

export function createApp() {
  const app = createSSRApp(App);
  // 注册插件
  app.use(FormPlugin); 
  return {
    app,
  };
}

2、在页面组件中使用

注意需要LayoutPageFormItem组件和useForm hook配合使用:

xml 复制代码
<template>
  <LayoutPage>
    <uni-card is-full>
      <uni-forms ref="formRef" :modelValue="formData" :rules="rules">
        <FormItem required label="姓名" name="name">
          <uni-easyinput type="text" v-model="formData.name" />
        </FormItem>
        <view style="margin-top: 70vh">
          <FormItem required label="年龄" name="age">
            <uni-easyinput type="text" v-model="formData.age" />

          </FormItem>
        </view>
        <view style="margin-top: 70vh">
          <FormItem required label="兴趣1" name="hobby">
            <uni-easyinput type="text" v-model="formData.hobby" />
          </FormItem>
        </view>
      </uni-forms>
    </uni-card>

    <template #footer>
      <view class="page-footer">
        <button type="primary" @click="submitForm">提交</button>
      </view>
    </template>
  </LayoutPage>
</template>

<script setup lang="ts">
import LayoutPage from '@/components/layout-page.vue'
import { useForm } from '@/hooks/form'
import FormItem from '@/components/form-item.vue'
import { ref } from 'vue'


const formData = ref({
  name: '',
  age: '',
  hobby: ''
})

const rules = {
  name: {
    rules: [
      {
        required: true,
        errorMessage: '请输入姓名',
      }
    ]
  },
  age: {
    rules: [
      {
        required: true,
        errorMessage: '请输入年龄',
      }
    ]
  },
  hobby: {
    rules: [
      {
        required: true,
        errorMessage: '请输入兴趣',
      }
    ]
  },
}

const { formRef, validate } = useForm()
const submitForm = async () => {
  try {
    const model = await validate()
    console.log(model)
  } catch (error) {
    console.error('表单错误', error)
  }
}
</script>

<style scoped lang="scss">
.page-footer {
  display: flex;
  background-color: #f8f8f8;

  button {
    flex: 1;
    margin: 10rpx;
  }
}
</style>

实现思路

  • 用一个全局响应式变量保存表单错误消息, 表单项监听这个变量的变化
  • 当表单校验失败时,将错误消息保存到这个变量中
  • 通过表单项的name属性和错误消息的key字段判断哪个表单项有错误
  • 滚动距离 0 位置设置一个锚点,当有错误时,通过表单项的位置和锚点的位置计算出滚动距离,然后滚动到错误的位置

表单错误消息示例

json 复制代码
[
  {
    "name": "name",
    "errorMessage": "请输入姓名"
  },
  {
    "name": "age",
    "errorMessage": "请输入年龄"
  },
  {
    "name": "hobby",
    "errorMessage": "请输入兴趣"
  }
]

核心逻辑流程图

  • 注1:重置错误消息可以防止重复执行,并且释放内存
  • 注2:计算目标滚动距离原理如下:

平台差异说明

App H5 微信小程序 支付宝小程序 百度小程序 抖音小程序、飞书小程序 QQ小程序 快手小程序 京东小程序
未测试 未测试 未测试 未测试 未测试 未测试 未测试

总结

通过nodesRef.boundingClientRect(callback)api配合锚点可计算出表单项的滚动距离,然后使用uni.pageScrollTo(OBJECT)可滚动相应位置。

但是由于小程序的限制,需要封装layout-page组件、二次封装uni-forms-item组件还有useForm hook配合,才能实现这个功能,实现方式和使用方式都较为复杂。

源码地址

示例页面源码

结语

感谢您耐心阅读这篇文章。如果您觉得内容对您有帮助或启发,请不吝点赞支持。如果您发现文章中的任何错误或需要改进的地方,欢迎您指正批评。

相关推荐
自然 醒9 小时前
uni-app开发微信小程序,如何使用towxml去渲染md格式和html标签格式的内容?
微信小程序·uni-app·html
CHB10 小时前
uni-agent,你的数字员工来了
人工智能·uni-app·vibecoding
h_jQuery10 小时前
uniapp使用canvas实现逐字书写任意文字内容,后合成一张图片提交
前端·javascript·uni-app
困困的果果头10 小时前
【uniapp】解决H5嵌套在web-view中时打包页面与状态栏重叠
前端·uni-app
前端 贾公子10 小时前
Uniapp 使用 UQRCode 创建二维码
uni-app
Rattenking10 小时前
uni-app组件开发----自定义数字键盘组件
前端·javascript·uni-app
竟未曾年少轻狂10 小时前
微信小程序-组件开发
微信小程序·小程序
想七想八不如1140812 小时前
【GitHub开源】一款极简跨平台 Todo 应用:微信小程序 + Windows 桌面挂件 + 实时同步
微信小程序·开源·github
笨笨狗吞噬者12 小时前
代理的妙用:uni-app 小程序是怎样用 `Proxy` 和 `wrapper` 抹平平台差异的
前端·微信小程序·uni-app
px不是xp2 天前
微信小程序组件化开发最佳实践
微信小程序·小程序·notepad++