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

源码地址

示例页面源码

结语

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

相关推荐
样子201828 分钟前
Uniapp 之renderjs解决swiper+多个video卡顿问题
前端·javascript·css·uni-app·html
fakaifa2 小时前
点大餐饮独立版系统源码v1.0.3+uniapp前端+搭建教程
小程序·uni-app·php·源码下载·点大餐饮·扫码点单
Bug改不动了5 小时前
React Native 与 UniApp 对比
react native·react.js·uni-app
anyup7 小时前
🔥🔥 10 天 Star 破百!uView Pro 文档也开源啦:完全免费、无广告、高效上手
前端·vue.js·uni-app
Dignity_呱8 小时前
如何在不发版时,实现小程序的 AB 测试?
前端·面试·微信小程序
fakaifa17 小时前
【最新版】CRMEB Pro版v3.4系统源码全开源+PC端+uniapp前端+搭建教程
人工智能·小程序·uni-app·php·crmeb·源码下载·crmebpro
2501_915918411 天前
iOS 应用上架全流程实践,从开发内测到正式发布的多工具组合方案
android·ios·小程序·https·uni-app·iphone·webview
咸虾米_1 天前
微信小程序通过uni.chooseLocation打开地图选择位置,相关设置及可能出现的问题
微信小程序·小程序·uniapp开发·小程序地图api
梦里寻码1 天前
自行食用 uniapp 多端 手写签名组件
前端·uni-app
不如摸鱼去2 天前
Trae 辅助下的 uni-app 跨端小程序工程化开发实践分享
微信小程序·小程序·uni-app·aigc·ai编程