先看看是不是你想要的:
需求:
有个填写数据的单子在提交的时候,会对必填项做校验,如果必填项没有数据的话,必填项校验生效给出提示,并且页面滚动到第一个需要填写数据的地方。
开发:
因为这个需求是后续增加的,那也不可能改变样式结构,那就在原来的基础上去写吧!
首先想到是用uniapp的内置方法pageScrollTo,这个方法可以让页面滚动到指定的位置,比较合适。
开始上手:
使用的vue3+js写法:
uni.pageScrollTo的参数:
selector使用子元素选择器:(在第二个view标签增加scrlloClass、第三个view标签增加scrollClass1类名)
-
子元素选择器:
.the-parent > .the-child
上代码:
const submit = () => {
// form表单绑定的是ref="form",因此使用使用form.value.validate方法对表单进行校验
form.value.validate().then(res => {
// 成功后的执行方法,即必填项都已经填写了
}).catch(err => {
// 失败后的方法,即有必填项没有填写
// 输出的是必填项未填写的数据信息
console.log('err', err);
// 上图中的form表单是有三个view标签,每个view标签中有多个uv-form-item标签,list数组是将第二个和第三个view标签的必填项(每个form-item标签上prop的字段)列举下来
let list = ["a", 'b', "c", "d", "e", "f", "g", "h"]
// 设置标签滚动位置
let scrollNum = undefined
// scrollObj是uni.pageScrollTo方法的参数,本文一共涉及到下面三个选项
let scrollObj = {
// scrollTop: 0, // 指定滚动到离顶部的距离
// duration: 500, // 滚动动画的时长
// selector: `.scrollClass > .uv-form-item:nth-child(${scrollNum})` // 指定滚动的元素
duration: 500,
}
// 先判断未填写的必填项中是否有name字段,没有的话接着走
if (err[0].field !== 'name') {
try { // 使用try catch中断forEach循环
list.forEach((e, i) => {
console.log('中断forEach');
if (e === err[0].field) {
scrollNum = i + 1 // 指定标签元素(nth-child是从1开始)
throw e // 抛给catch
}
})
} catch (e) {
scrollObj.selector = `.scrollClass > .uv-form-item:nth-child(${scrollNum})`
if (e === 'name') {
// 上图中的form表单是有三个view标签,给第三个form-item标签增加一个scrollClass1类名
scrollObj.selector = `.scrollClass1 > .uv-form-item:nth-child(1)`
}
}
console.log('scrollNum', scrollNum);
} else {
// 有name字段的话,将scrollTop设置为0,及滚动到页面顶部(第一个view标签,见gif动图的第一块区域)
scrollObj.scrollTop = 0
}
uni.pageScrollTo(scrollObj);
})
}
问题解决无非就是获取必填项未填写的数组(下文称为arr),及validate方法的catch方法中的err,将必填项的字段标识放到一个新数组里面,拿到arr的第一项的field(第一个必填项的字段的标识),循环新数组,如果新数组每一项和arr的第一项的field相等的话,拿到该项索引,索引加1,用于确定滚动到该标签。