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、在页面组件中使用

注意需要LayoutPage、FormItem组件和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配合,才能实现这个功能,实现方式和使用方式都较为复杂。

源码地址

示例页面源码

结语

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

相关推荐
andrsted2 小时前
练题簿在线免费刷题:Word、PDF 导题与预览补全,把现成资料变成可练习题库
微信小程序·小程序·pdf·word·学习方法·刷题
Geek_Vison3 小时前
保险APP已经用了Flutter,还能接入小程序吗?
flutter·小程序·uni-app·mpaas·小程序容器
计算机毕设定制辅导-无忧学长4 小时前
《校园食堂在线订餐小程序的设计与实现》
java·vue.js·spring boot·微信小程序·uniapp·校园食堂在线订餐小程序
郑州光合科技余经理14 小时前
本地生活平台搭建:跨业态用户标识怎么贯通
java·开发语言·前端·后端·uni-app·php·ai编程
2501_915909061 天前
iOS应用从开发到上架App Store的完整发布流程与步骤指南
android·ios·小程序·https·uni-app·webview
不爱说话郭德纲2 天前
从“点点点”到一键出包:我把 uni-app x Android 离线打包做成了脚本
android·前端·uni-app
snotJam2 天前
关于Uniapp的Android自定义基座使用
android·uni-app
andrsted2 天前
练题簿在线免费刷题:听读练题支持暂停续播、循环播放,让自己的题库听得更方便
学习·微信小程序·小程序·刷题·在线刷题
今年下半年3 天前
【微信小程序】uni-app + Vue3 + Vite 的小程序项目实现「进入指定范围才能打卡」的考勤功能
微信小程序·uni-app·定位·考勤
xinraynet3 天前
沈阳企业小程序开发选型:五个可核验维度,附设备数据采集与私域商城的技术实现要点
大数据·科技·ai·微信小程序·小程序