使用el-form之表單校驗(yàn)自動(dòng)定位到報(bào)錯(cuò)位置問題
1. 背景
表單校驗(yàn)大多數(shù)的表單都會(huì)用到,一般情況下只是提示當(dāng)前哪些項(xiàng)校驗(yàn)不通過,但是如果表單比較需要用戶自己去找是哪項(xiàng)校驗(yàn)不通過,這樣的用戶體驗(yàn)不太好,如果能自動(dòng)定位到當(dāng)前校驗(yàn)不通過的表單項(xiàng)體驗(yàn)會(huì)更好一些(這里是以elementui 的 el-from 組件為例子)
2. 實(shí)現(xiàn)思路
目前有兩個(gè)實(shí)現(xiàn)方法:
方法一
表單校驗(yàn)不通過的時(shí)候,會(huì)在未校驗(yàn)成功的表單 el-form-item 標(biāo)簽上加一個(gè)類名 is-error,可以從這個(gè)類名下手,獲取當(dāng)前校驗(yàn)不通過的所有的類名,然后通過 scrollIntoView 方法進(jìn)行自動(dòng)滑動(dòng)到當(dāng)前報(bào)錯(cuò)的表單項(xiàng)位置

方法二
利用el-form提供的 validate 方法的第二個(gè)參數(shù),獲取當(dāng)前校驗(yàn)不通過的rule 對(duì)象,獲取到報(bào)錯(cuò)的 prop 后,在每個(gè)需要加表單校驗(yàn)的項(xiàng)上加上 ref,ref 的綁定值和 prop 保持一致這樣方便直接定位到哪個(gè)prop,然后和第一個(gè)方法一樣利用 scrollIntoView 方法結(jié)合$ref 獲取到 $el 實(shí)現(xiàn)自動(dòng)定位到校驗(yàn)不通過的表單項(xiàng)

3. 實(shí)現(xiàn)代碼
方法一
實(shí)現(xiàn)代碼:
// 表單校驗(yàn)
verifyForm() {
this.$refs.basicInfoRule.validate(valid => {
if (valid) {
// 校驗(yàn)通過執(zhí)行的邏輯
} else {
// 校驗(yàn)不通過自動(dòng)定位到不通過的表單項(xiàng)
this.moveToErr()
}
})
},
// 自動(dòng)定位到表單報(bào)錯(cuò)項(xiàng)
moveToErr() {
this.$nextTick(() => {
let isError = document.getElementsByClassName('is-error')
if (isError.length) {
isError[0].scrollIntoView({
block: 'center',
behavior: 'smooth'
})
// 這個(gè)當(dāng)滑動(dòng)到報(bào)錯(cuò)項(xiàng)之后自動(dòng)獲取輸入框的焦點(diǎn),方便用戶直接進(jìn)行輸入,延遲 800ms 是因?yàn)樾枰寄艿蕉ㄎ怀晒笤谶M(jìn)行獲取焦點(diǎn)體驗(yàn)更好一些
setTimeout(() => {
if (isError[0].previousElementSibling.querySelector('input')) {
isError[0].previousElementSibling.querySelector('input').focus()
}
}, 800)
}
})
}方法二
實(shí)現(xiàn)代碼:
模板示例代碼
<el-form-item label="姓名:" prop="name" ref="name">
<el-input
v-model.number="form."
placeholder="請(qǐng)輸入姓名"
clearable
></el-input>
</el-form-item> verifyForm() {
this.$refs.ruleForm.validate((valid, object) => {
if (valid) {
//校驗(yàn)通過執(zhí)行邏輯
} else {
let errorArr = [];
for (let key in object) {
object[key].forEach((item) => {
errorArr.push(item.message);
});
let dom = this.$refs[Object.keys(object)[0]];
if (Object.prototype.toString.call(dom) !== '[object Object]') {
dom = dom[0];
break; //結(jié)束語句并跳出語句,進(jìn)行下個(gè)語句執(zhí)行
}
// 定位到報(bào)錯(cuò)項(xiàng)
dom.$el.scrollIntoView({
block: 'center',
behavior: 'smooth',
});
}
// 頁面提示未通過校驗(yàn)字段項(xiàng),
this.$message.error(errorArr[0]);
}
});
},4. 拓展(踩坑…)
由于頁面比較復(fù)雜分了好幾個(gè)子組件,而且子組件中都有需要校驗(yàn)的表單項(xiàng),在父組件保存表單前,需要調(diào)用各個(gè)子組件的表單校驗(yàn)方法,發(fā)現(xiàn)el-form 的 validate 方法不能返會(huì)校驗(yàn)失敗還是校驗(yàn)成功
錯(cuò)誤代碼示范:
// 子組件代碼
verifyForm() {
this.$refs.basicInfoRule.validate(valid => {
if (valid) {
// 校驗(yàn)通過
return true
} else {
// 校驗(yàn)不通過
return false
}
})
},
// 父組件代碼
// 校驗(yàn)子組件表單(通過子組件綁定的ref來調(diào)用子組件的校驗(yàn)方法)
async handleVerify() {
if (
!(await this.$refs.basicInfo?.verifyForm()) ||
!(await this.$refs.priceSetting?.verifyForm())
) {
this.$message.warning('請(qǐng)完善表單必填項(xiàng)')
return false
}
return true
},
// 保存
async saveMainDetail() {
try {
if (!(await this.handleVerify())) return
} catch (e) {} 上述代碼在父組件里面不能獲取到組件的校驗(yàn)狀態(tài),子組件換一個(gè)寫法就行了
正確代碼示范:
使用 Promise 來返回表單的是否校驗(yàn)成功狀態(tài)能在父組件成功拿到了
// 子組件代碼
verifyForm() {
return new Promise((resolve, reject) => {
this.$refs.basicInfoRule.validate(valid => {
if (valid) {
console.log(valid, '校驗(yàn)通過')
resolve(true)
} else {
console.log(valid, '校驗(yàn)不通過')
reject(new Error())
}
})
})
}心得:
實(shí)現(xiàn)功能的思路有很多,這里我列舉出來的兩種,看實(shí)際的功能和需求找到適合自己的方法~
el-form校驗(yàn)失敗時(shí)定位到失敗項(xiàng)
需求
提交的表單過長,出現(xiàn)滾動(dòng)條時(shí),點(diǎn)擊‘確定’觸發(fā)表單檢驗(yàn)后,頁面看不到的表單項(xiàng)報(bào)錯(cuò),但是用戶在頁面不能感知到,這時(shí)需要將滾動(dòng)條滾動(dòng)至校驗(yàn)失敗項(xiàng)處。
如圖:控制臺(tái)提示校驗(yàn)失敗,頁面顯示正常,用戶無感知。

思路
表單校驗(yàn)失敗時(shí),失敗項(xiàng)有is-error類,獲取這個(gè)元素,使用scrollIntoView()方法。
scollIntoView()將調(diào)用它的元素滾動(dòng)到瀏覽器窗口的可見區(qū)域。

js代碼
moveToErr () {
this.$nextTick(() => {
let isError = document.getElementsByClassName('is-error')
if (isError.length) {
isError[0].scrollIntoView({
block: 'center',
behavior: 'smooth'
})
}
})
}總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- el-form實(shí)現(xiàn)表單和圖片手動(dòng)上傳和校驗(yàn)功能
- vue實(shí)現(xiàn)多個(gè)el-form表單提交統(tǒng)一校驗(yàn)的2個(gè)方法
- elementUI動(dòng)態(tài)嵌套el-form表單校驗(yàn)舉例詳解
- vue中的el-form表單rule校驗(yàn)問題(特殊字符、中文、數(shù)字等)
- vue之el-form表單校驗(yàn)以及常用正則詳解
- el-form的model、prop屬性和表單校驗(yàn)等使用
- v-for中動(dòng)態(tài)校驗(yàn)el-form表單項(xiàng)的實(shí)踐
- el-form表單實(shí)現(xiàn)校驗(yàn)的示例代碼
相關(guān)文章
Vue3使用vue-office插件實(shí)現(xiàn)word預(yù)覽功能
vue-office是一個(gè)支持多種文件(docx、.xlsx、pdf)預(yù)覽的vue組件庫,支持vue2和vue3,這篇文章主要介紹了Vue3使用vue-office插件實(shí)現(xiàn)word預(yù)覽功能,需要的朋友可以參考下2024-04-04
vue實(shí)現(xiàn)接口封裝的實(shí)現(xiàn)示例
本文主要介紹了vue實(shí)現(xiàn)接口封裝的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-11-11
解決vue3傳屬性時(shí)報(bào)錯(cuò)[Vue?warn]:Component?is?missing?template?or
這篇文章主要給大家介紹了關(guān)于解決vue3傳屬性時(shí)報(bào)錯(cuò)[Vue?warn]:Component?is?missing?template?or?render?function的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-01-01
vue構(gòu)建單頁面應(yīng)用實(shí)戰(zhàn)
本篇文章主要介紹了vue構(gòu)建單頁面應(yīng)用實(shí)戰(zhàn),使用 SPA,沒有頁面切換,就沒有白屏阻塞,可以大大提高 H5 的性能,達(dá)到接近原生的流暢體驗(yàn)。2017-04-04
實(shí)例詳解Vue項(xiàng)目使用eslint + prettier規(guī)范代碼風(fēng)格
這篇文章主要介紹了Vue項(xiàng)目使用eslint + prettier規(guī)范代碼風(fēng)格,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2018-08-08
Vue出現(xiàn)彈出層時(shí)禁止底部頁面跟隨滑動(dòng)
本文主要介紹了Vue出現(xiàn)彈出層時(shí)禁止底部頁面跟隨滑動(dòng),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07

