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

源码地址

示例页面源码

结语

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

相关推荐
努力成为包租婆5 小时前
微信小程序 van-dropdown-menu
微信·微信小程序·小程序
thinkQuadratic7 小时前
微信小程序动态设置高度,添加动画等常用操作
微信小程序·小程序
幽络源小助理10 小时前
微信小程序文章管理系统开发实现
java·微信小程序·springboot
10年前端老司机11 小时前
微信小程序模板语法和事件
前端·javascript·微信小程序
xx240612 小时前
UniApp学习笔记
uni-app
上趣工作室12 小时前
微信小程序开发1------微信小程序中的消息提示框总结
微信小程序·小程序
三天不学习14 小时前
微信小程序蓝牙连接打印机打印单据完整Demo【蓝牙小票打印】
微信小程序·小程序·蓝牙打印
七七小报16 小时前
uniapp-商城-36-shop 购物车 选好了 进行订单确认2 支付方式颜色变化和颜色滤镜filter
uni-app
lh_125416 小时前
uniapp 常用开发技巧与实战指南
uni-app
某公司摸鱼前端17 小时前
uniapp 仿企微左边公司切换页
前端·uni-app·企业微信