CNCEC_APP/uni_modules/uview-pro/components/u-form/u-form.vue

136 lines
4.3 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="u-form" :class="customClass" :style="$u.toStyle(customStyle)">
<slot />
</view>
</template>
<script lang="ts">
export default {
name: 'u-form',
options: {
addGlobalClass: true,
// #ifndef MP-TOUTIAO
virtualHost: true,
// #endif
styleIsolation: 'shared'
}
};
</script>
<script setup lang="ts">
import { FormProps } from './types';
import { computed, ref } from 'vue';
import { $u, useParent } from '../..';
/**
* form 表单
* @description 此组件一般用于表单场景可以配置Input输入框Select弹出框进行表单验证等。
* @tutorial https://uviewpro.cn/zh/components/form.html
* @property {Object} model 表单数据对象
* @property {Boolean} border-bottom 是否显示表单域的下划线边框
* @property {String} label-position 表单域提示文字的位置left-左侧top-上方
* @property {String Number} label-width 提示文字的宽度单位rpx默认90
* @property {Object} label-style label的样式对象形式
* @property {String} label-align label的对齐方式
* @property {Object} rules 通过ref设置见官网说明
* @property {Array} error-type 错误的提示方式,数组形式,见上方说明(默认['message'])
* @example <u-form :model="form" ref="uForm"></u-form>
*/
const props = defineProps(FormProps);
useParent('u-form');
interface ErrorItem {
prop: string;
message: string;
}
// 存储当前form下的所有u-form-item的实例
const fields = ref<any[]>([]);
// 校验规则
const rules = ref<Record<string, any>>(props.rules);
/**
* 设置校验规则
* @param newRules 校验规则对象
*/
function setRules(newRules: Record<string, any>) {
rules.value = newRules;
}
/**
* 清空所有u-form-item组件的内容本质上是调用了u-form-item组件中的resetField()方法
*/
function resetFields() {
fields.value.forEach((field: any) => {
field.resetField && field.resetField();
});
}
/**
* 校验全部数据
* @param callback 校验回调
* @returns Promise<boolean>
*/
function validate(callback?: (valid: boolean, errorArr: ErrorItem[]) => void): Promise<boolean> {
return new Promise(resolve => {
// 对所有的u-form-item进行校验
let valid = true; // 默认通过
let count = 0; // 用于标记是否检查完毕
let errorArr: ErrorItem[] = []; // 存放错误信息
if (fields.value.length === 0) {
resolve(true);
if (typeof callback === 'function') callback(true, []);
return;
}
// 调用每一个u-form-item实例的validation的校验方法
fields.value.forEach((field: any) => {
// 如果任意一个u-form-item校验不通过就意味着整个表单不通过
field.validation &&
field.validation('', (error: any) => {
if (error) {
valid = false;
errorArr.push({ prop: field.prop, message: error });
}
// 当历遍了所有的u-form-item时调用promise的then方法
if (++count === fields.value.length) {
resolve(valid); // 进入promise的then方法
// 判断是否设置了toast的提示方式只提示最前面的表单域的第一个错误信息
if (
props.errorType.indexOf('none') === -1 &&
props.errorType.indexOf('toast') >= 0 &&
errorArr.length > 0
) {
errorArr[0].message && $u.toast(errorArr[0].message);
}
// 调用回调方法
if (typeof callback === 'function') callback(valid, errorArr);
}
});
});
});
}
defineExpose({
setRules,
resetFields,
validate,
addField(field: any) {
if (!fields.value.includes(field)) fields.value.push(field);
},
removeField(field: any) {
fields.value = fields.value.filter(f => f.prop !== field.prop);
},
fields,
rules,
props,
model: computed(() => props.model)
});
</script>
<style scoped lang="scss">
@import '../../libs/css/style.components.scss';
</style>