151 lines
3.3 KiB
Vue
151 lines
3.3 KiB
Vue
<!-- 待完成 -->
|
||
<template>
|
||
|
||
<view>
|
||
<slot></slot>
|
||
</view>
|
||
|
||
</template>
|
||
|
||
<script setup>
|
||
import { reactive, ref, onMounted, provide, computed } from 'vue'
|
||
import infoBox from '@/commons/utils/infoBox.js'
|
||
|
||
|
||
// 定义组件参数
|
||
const props = defineProps({
|
||
|
||
// 验证规则
|
||
rules: { type: Object, default: () => { } },
|
||
|
||
// 用作表单验证
|
||
model: { type: Object, default: () => { } },
|
||
|
||
|
||
|
||
})
|
||
|
||
const vdata = reactive({
|
||
formNameList: [], // form 表单的已经注册的名字集合
|
||
|
||
errorListByText: [], // 错误信息集合 ( 需要显示的 )
|
||
errorListByToast: [], // 错误信息集合 ( alert 提示的 )
|
||
|
||
|
||
})
|
||
|
||
|
||
// 组件注册 和 取消
|
||
function itemSign(name){
|
||
|
||
if(vdata.formNameList.indexOf(name) < 0){
|
||
vdata.formNameList.push(name)
|
||
}
|
||
|
||
}
|
||
|
||
// 组件注册 和 取消
|
||
function unItemSign(name){
|
||
if(vdata.formNameList.indexOf(name) >= 0){
|
||
vdata.formNameList.splice(vdata.formNameList.indexOf(name), 1)
|
||
}
|
||
}
|
||
|
||
// { type: String, required: true, message: '', showToastError: false, validator: (rule, value) => {} }
|
||
|
||
// showTextError : 是否显示文本错误, 默认为true
|
||
// showToastError: 是否alert信息, 默认为:false
|
||
|
||
// 错误条目数据结构: {name, value, rule, errorMsg}
|
||
// 注意: errorMsg 跟 rule里的 message不是一回事, errorMsg 可能是 回调函数自定义。
|
||
function pushError(name, value, errorMsg, rule){
|
||
|
||
// 明确是 false, 则不加入文本错误信息, 未定义等都是true(默认值)
|
||
if(rule.showTextError === false){
|
||
}else{
|
||
vdata.errorListByText.push({name, value, rule, errorMsg})
|
||
}
|
||
|
||
// alert 默认为 false
|
||
if(rule.showToastError === true){
|
||
vdata.errorListByToast.push({name, value, rule, errorMsg})
|
||
}
|
||
}
|
||
|
||
|
||
function validateFormItem(name){
|
||
|
||
// 不存在
|
||
if(!name || !props.rules[name] ){
|
||
return false
|
||
}
|
||
|
||
// model的值
|
||
const value = props.model[name]
|
||
|
||
props.rules[name].forEach( rule => {
|
||
|
||
// 必填 && 验证失败
|
||
if(rule.required && (value == null || value == '' || typeof value == 'undefined')){
|
||
pushError(name, value, rule.message, rule)
|
||
|
||
}else{ // 非必填 || 必填验证通过
|
||
|
||
if(rule.validator){ // 包含验证自定义函数, 暂时先不支持promise
|
||
|
||
let validatorResult = rule.validator(rule, value)
|
||
if( validatorResult == true){ // 验证通过
|
||
|
||
}else{ // 验证失败
|
||
pushError(name, value, validatorResult, rule)
|
||
}
|
||
}
|
||
}
|
||
})
|
||
return false;
|
||
}
|
||
|
||
|
||
|
||
// 表单验证 , 返回Promise
|
||
function validate(){
|
||
|
||
// 清空错误信息
|
||
vdata.errorListByText = []
|
||
vdata.errorListByToast = []
|
||
|
||
vdata.formNameList.forEach(name => validateFormItem(name) )
|
||
|
||
if(vdata.errorListByToast && vdata.errorListByToast.length > 0){
|
||
infoBox.showToast(vdata.errorListByToast[0].errorMsg)
|
||
}
|
||
|
||
console.log(vdata.formNameList);
|
||
console.log(vdata.errorListByText);
|
||
console.log(vdata.errorListByToast);
|
||
|
||
if(vdata.errorListByText.length <= 0 && vdata.errorListByToast.length <= 0){
|
||
alert('成功')
|
||
}
|
||
|
||
}
|
||
|
||
|
||
|
||
// 向下注册的组件
|
||
const provideModel = {
|
||
itemSign: itemSign,
|
||
unItemSign: unItemSign,
|
||
}
|
||
|
||
|
||
provide('jeepayForm', computed( ()=> provideModel ) )
|
||
|
||
// provideModel 写入: errorListByText 监听不到。
|
||
provide('jeepayErrorListByText', computed( ()=> vdata.errorListByText ) )
|
||
|
||
defineExpose({ validate })
|
||
</script>
|
||
|
||
<style>
|
||
</style> |