1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
| <script setup>
| import { computed, ref, watch, onMounted, reactive, toRefs } from 'vue'
| import { validationRules, combineRule } from '../../lib/js/rule.js'
| const props = defineProps({
| value: '',
| rules: {
| type: Array,
| default: []
| },
| lazy: { // 懒验证 关闭后实时验证
| type: Boolean,
| default: true
| },
| model: '',
| })
| const emit = defineEmits(['error'])
|
| const state = reactive({
| valid: false, // 验证是否通过
| error: '', // 错误信息
| dirty: false, // 是否污染
| rule: ''
| })
|
| const rules = computed(() => combineRule(props.rules))
|
| watch(() => props.value, () => {
| check()
| if (state.dirty) return
| state.dirty = true
| }, { deep: true })
|
| function setState(name, value) {
| state[name] = value
| }
|
| function getState(name) {
| return name ? state[name] : state
| }
|
| function valided(rule, value) {
| const { type, message } = rule
| const status = validationRules[type](rule.value, value, props.model)
| setState('error', status ? '' : message)
| setState('valid', status)
| setState('rule', {rule, value})
|
| if(!status) {
| emit('error', message)
| }
| return status
| }
|
| function check() {
| if (rules.value.length) {
| return rules.value.every(rule => {
| return valided(rule, props.value)
| })
| }
| setState('valid', true)
| return true
| }
|
| function reset() {
| state.valid = false
| state.error = ''
| state.dirty = false
| }
|
| onMounted(() => {
| if (!props.lazy) {
| check()
| }
| })
|
| defineExpose({
| ...toRefs(state),
| check,
| reset,
| getState
| })
| </script>
|
| <template>
| <view>
| <slot></slot>
| </view>
| </template>
|
|