Skip to content

Commit ba50bc7

Browse files
committed
feat(Form Validation): Add throttle to form validation
1 parent fee6e44 commit ba50bc7

2 files changed

Lines changed: 30 additions & 12 deletions

File tree

src/components/form/index.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -467,13 +467,15 @@ Clair 目前支持验证的 `type` 有:
467467

468468
某些情况下,输入的验证过程是异步的(比如需要调用服务器端接口去验证)。你可以自定义一个异步的验证函数,让这个函数返回一个 `Promise` 即可。
469469

470+
对于需要访问 HTTP 接口进行异步校验的场景,我们通常需要对验证函数进行节流处理。通过 `validate-throttle` 属性可以指定进行验证的最小时间间隔。
471+
470472
```html
471-
<c-input v-model="user" :rules="rules" placeholder="请输入用户名" />
473+
<c-input v-model="user" :rules="rules" placeholder="请输入用户名" :validate-throttle="500" />
472474

473475
<script>
474476
const rules = {
475-
required: true,
476477
available: function (val) {
478+
console.log(`validating value ${val}`)
477479
return new Promise((resolve, reject) => {
478480
// 这里模拟一个异步验证
479481
setTimeout(() => {

src/scripts/mixins/validatable/index.js

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,18 @@
33
*/
44
import Validator from './validator.js'
55
import { isPromise } from './util.js'
6+
import throttle from 'lodash/throttle'
67

78
export default {
89

910
props: {
1011
rules: {
1112
type: Object,
1213
default: _ => ({})
14+
},
15+
validateThrottle: {
16+
type: Number,
17+
default: 0
1318
}
1419
},
1520

@@ -22,7 +27,8 @@ export default {
2227
dirty: false
2328
},
2429
isValidatable: true,
25-
asyncValidationId: 0
30+
// id of the latest validation
31+
validationId: 0
2632
}
2733
},
2834

@@ -59,7 +65,16 @@ export default {
5965
watch: {
6066
value () {
6167
if (this.validity.dirty) {
62-
this.validate()
68+
this.throttledValidate()
69+
}
70+
},
71+
validateThrottle: {
72+
immediate: true,
73+
handler (duration) {
74+
if (!duration) this.throttledValidate = this.validate
75+
this.throttledValidate = throttle(this.validate, duration, {
76+
trailing: true
77+
})
6378
}
6479
}
6580
},
@@ -78,16 +93,17 @@ export default {
7893
}
7994
const result = Validator.validate(this.value, rules)
8095
const setValidity = v => Object.assign(this.validity, v)
81-
if (isPromise(result)) {
82-
this.asyncValidationId++
83-
(() => {
84-
const id = this.asyncValidationId
96+
const isLatest = id => this.validationId === id
97+
{
98+
this.validationId++
99+
let { validationId } = this
100+
if (isPromise(result)) {
85101
result.then(v => {
86-
if (this.asyncValidationId === id) setValidity(v)
102+
if (isLatest(validationId)) setValidity(v)
87103
})
88-
})()
89-
} else {
90-
setValidity(result)
104+
} else {
105+
setValidity(result)
106+
}
91107
}
92108
return result
93109
},

0 commit comments

Comments
 (0)