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配合,才能实现这个功能,实现方式和使用方式都较为复杂。

源码地址

示例页面源码

结语

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

相关推荐
行思理17 小时前
微信小程序上如何使用图形验证码
微信小程序·小程序
xiyueta19 小时前
使用cursor ai 开发 UniApp JSON 工具开发文档
uni-app·json
浮生若梦l1 天前
原生android 打包.aar到uniapp使用
android·java·uni-app
优雅格子衫1 天前
记录uniapp小程序对接腾讯IM即时通讯无ui集成(2)
小程序·uni-app
尚学教辅学习资料1 天前
基于SSM+Vue+uniapp的考研交流(带商城)小程序+LW示例参考
vue.js·考研·uni-app
ZJL-阿友1 天前
uniapp简单可分享的电子名片
uni-app
啊吨吨吨OOO。1 天前
uniapp+vue3搭建项目
前端·javascript·uni-app
优雅格子衫1 天前
uniapp小程序对接腾讯IM即时通讯无ui集成(1)
小程序·uni-app
小钟H呀1 天前
uniapp 常用 UI 组件库
ui·uni-app