'f'
mh-two-thousand-and-two
2024-04-12 67be16f91562283e4ce6e999696101817fba767f
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>