This commit is contained in:
xuziqiang
2024-05-15 17:29:42 +08:00
commit d0155dbe3c
7296 changed files with 1832517 additions and 0 deletions

View File

@@ -0,0 +1,122 @@
<!-- @format -->
<template>
<a-row class="ns-form-body" :justify="formLayout.justify">
<a-col :span="24" class="ns-child-form-title" v-html="title" v-if="title" />
<template v-for="(schema, index) in getSchema" :key="schema.field">
<ns-form-item
:span="getComponentSpan(schema)"
:schema="schema"
:index="index"
:formModel="formModel">
<template #[item]="data" v-for="item in Object.keys($slots)">
<slot :name="item" v-bind="data || {}"></slot>
</template>
</ns-form-item>
</template>
<!-- 占位解决三列中部为空的问题 -->
<a-col :span="formLayout.span" class="ns-form-item ns-form-item-placeholder" />
</a-row>
<a-divider class="ns-child-form-divider" />
</template>
<script lang="ts">
import type { PropType } from 'vue';
import { computed, defineComponent, inject, ref, watch } from 'vue';
import { useFormModel } from '/nerv-lib/component/form/form/use-form-model';
export default defineComponent({
name: 'NsChildForm',
props: {
title: {
type: String,
default: '',
},
schemas: {
type: Array as PropType<FormSchema[]>,
default: () => [],
},
formModel: {
type: Object as PropType<Recordable>,
default: () => ({}),
},
},
setup(props, { attrs, slots }) {
const formElRef = ref();
// const addChildForm = inject('addChildForm');
const formLayout = inject('formLayout');
// formElRef.value ? addChildForm(formElRef) : '';
// addChildForm(formElRef);
const getBindValue = computed(() => ({
...attrs,
...props,
}));
const getComponentSpan = (schema: FormSchema) => {
if (schema.class?.includes('ns-form-item-full')) {
return 24;
}
return formLayout?.span;
};
const getSchema = computed((): FormSchema[] => {
const { schemas } = props;
const formSchemas = schemas.filter((schema) => schema.component);
return formSchemas as FormSchema[];
});
const isInitDefaultValueRef = ref(false);
const {
handleFormModel,
initFormModel,
resetFormModel,
setFormModel,
unsetFormModel,
getFormModel,
} = useFormModel({
schemas: props.schemas,
formModel: props.formModel,
formElRef,
});
watch(
() => getSchema.value,
() => {
if (isInitDefaultValueRef.value) {
return;
}
initFormModel();
isInitDefaultValueRef.value = true;
},
{
immediate: true,
deep: true,
},
);
return {
formElRef,
getBindValue,
formLayout,
getSchema,
getComponentSpan,
};
},
});
</script>
<style lang="less" scoped>
.ns-child-form-title {
font-size: 16px;
font-weight: bold;
line-height: 24px;
padding: 32px 0 24px 0;
}
.ns-child-form-divider {
margin: 8px 0 0 0;
}
.ns-form-item-placeholder {
min-height: 0;
height: 0;
}
</style>

View File

@@ -0,0 +1,335 @@
<!-- @format -->
<template>
<a-col
:span="span"
class="ns-form-item"
:class="getFormItemClass"
v-if="getIfShow"
v-show="getShow">
<a-form-item v-if="getFormItemDisplay" v-bind="formItemProps">
<template #[item]="data" v-for="item in Object.keys(getSlots)">
<slot :name="schema.field + '_' + item" v-bind="data || {}"></slot>
</template>
<component :is="schema.component" v-bind="formProps">
<template #[item]="data" v-for="item in Object.keys($slots)">
<slot :name="item" v-bind="data || {}"></slot>
</template>
</component>
<!-- <div class="ns-tips">-->
<!-- <slot :name="`${schema.field}_tips`"></slot>-->
<!-- </div>-->
</a-form-item>
<template v-else>
<component :is="schema.component" v-bind="formProps">
<template #[item]="data" v-for="item in Object.keys($slots)">
<slot :name="item" v-bind="data || {}"></slot>
</template>
</component>
<!-- <div class="ns-tips">-->
<!-- <slot :name="`${schema.field}_tips`"></slot>-->
<!-- </div>-->
</template>
</a-col>
</template>
<script lang="ts">
import type { PropType } from 'vue';
import { computed, defineComponent, inject, nextTick, provide, ref, unref } from 'vue';
import {
forEach,
isArray,
isBoolean,
isFunction,
isObject,
isString,
isUndefined,
mapKeys,
upperFirst,
get,
} from 'lodash-es';
import { isInputType } from '/nerv-lib/component/form/form-util';
import { useParams } from '/nerv-lib/use/use-params';
export default defineComponent({
name: 'NsFormItem',
components: {},
props: {
span: Number,
schema: {
type: Object as PropType<FormSchema>,
default: () => ({}),
},
show: {
type: Boolean,
default: true,
},
formModel: {
type: Object as PropType<Recordable>,
default: () => ({}),
},
index: {
type: Number,
default: 0,
},
},
setup(props, { slots }) {
const components = inject('components', () => ({}))();
const setFormModel = inject('setFormModel') as Function;
const getFormModel = inject('getFormModel') as Function;
const submit = inject('submit') as Function;
const validateRef = ref({});
const formLayout = inject('formLayout');
const { getParams } = useParams();
const getSlots = computed(() => {
const { schema } = props;
return mapKeys(slots, (_val, key) => {
return schema.field ? key.replace(schema.field + '_', '') : key;
});
});
provide(
'rules',
computed(() => {
return props.schema?.rules || [];
}),
);
const formItemProps = computed(() => {
const {
schema: { field, rules, label, component, autoLink, formItemProps, extra },
} = props;
const tableComponent = ['nsTable'];
let nsClass = '';
component && tableComponent.includes(component) && (nsClass = 'ns-form-item-validate-self');
return {
class: nsClass,
name: field,
rules: rules || [],
label: label,
autoLink: autoLink || true,
extra: extra,
...formItemProps,
...validateRef.value,
};
});
const getFormItemDisplay = computed(() => {
const { schema } = props;
return schema.displayFormItem !== false;
});
const getFormItemClass = computed(() => {
const { schema } = props;
return schema.class;
});
const getDisabled = computed(() => {
const { dynamicDisabled } = props.schema;
if (dynamicDisabled) {
if (isBoolean(dynamicDisabled)) {
return { disabled: dynamicDisabled };
}
if (isFunction(dynamicDisabled)) {
return { disabled: dynamicDisabled(props.formModel) };
}
return {};
}
return {};
});
const getIfShow = computed(() => {
const { ifShow } = props.schema;
let isIfShow = true;
if (isBoolean(ifShow)) {
isIfShow = ifShow;
}
if (isFunction(ifShow)) {
isIfShow = ifShow(props.formModel);
}
// 不显示时候删除属性
if (!isIfShow) {
setFormModel(props.schema.field, null);
}
return isIfShow && props.show;
});
const getShow = computed(() => {
const { show } = props.schema;
let isShow = true;
if (isBoolean(show)) {
isShow = show;
}
if (isFunction(show)) {
isShow = show(props.formModel);
}
return isShow;
});
// console.log(props.schema?.field, getShow.value, props.schema);
const getDynamicParams = computed(() => {
const { dynamicParams, defaultParams, componentProps = {} } = props.schema;
const { params = {} } = componentProps;
if (dynamicParams) {
const data = getParams(props.formModel, dynamicParams, { ...params, ...defaultParams });
// console.log('getParams', data);
return data;
} else {
return { ...params, ...defaultParams };
}
});
/**
* 检测requiredParams是否全部获得数据
* @param params
*/
function checkRequiredParams(params: Recordable) {
const { dynamicParams } = props.schema;
let { requiredParams } = props.schema;
if (requiredParams) {
if (requiredParams === true) requiredParams = dynamicParams as any;
if (isFunction(requiredParams)) {
console.error(
'Property dynamicParams of props cannot set to Function when using requiredParams',
);
return false;
} else {
if (isString(requiredParams)) {
if (isUndefined(params[requiredParams])) return false;
} else if (isArray(requiredParams)) {
for (let i = 0, l = requiredParams.length; i < l; i++) {
if (isUndefined(params[requiredParams[i]])) return false;
}
} else if (isObject(requiredParams)) {
const keys = Object.keys(requiredParams);
for (let i = 0, l = keys.length; i < l; i++) {
if (isUndefined(params[keys[i]])) return false;
}
}
}
return true;
}
return true;
}
const formProps = computed(() => {
const { formModel } = props;
const {
component,
field,
dynamicParams,
changeEvent = 'change',
valueField,
addModel = [],
autoAddLink = false,
autoSubmit = false,
} = props.schema;
const isCheck =
component && ['NsSwitch', 'NsCheckbox', 'Switch', 'Checkbox'].includes(component);
const eventKey = `on${upperFirst(changeEvent)}`;
const attr: Recordable = {};
if (isInputType(component)) {
attr.allowClear = true;
}
const propsData: Recordable = {
field,
dynamicParams,
...attr,
size: 'default',
...unref(getComponentsProps),
...unref(getDisabled),
};
// 如果有值
if (getDynamicParams.value) {
if (props.schema?.requiredParams) {
if (checkRequiredParams(getDynamicParams.value)) {
propsData.params = getDynamicParams.value;
propsData.checkRequiredParams = true;
} else {
propsData.checkRequiredParams = false;
}
} else {
propsData.params = getDynamicParams.value;
}
}
const bindValue: Recordable = {
[valueField || (isCheck ? 'checked' : 'value')]: props.formModel[field],
};
const on = {
[eventKey]: (...args: Nullable<Recordable>[]) => {
const [e] = args;
if (propsData[eventKey]) {
(propsData[eventKey] as Function)(...args);
}
const target = e ? e.target : null;
const value = target ? (isCheck ? target.checked : target.value) : e;
setFormModel(field, value);
if (isArray(addModel)) {
addModel.forEach((item) => {
setFormModel(item, args[1] && args[1][item]);
});
} else {
forEach(addModel as any, (value, key) => {
setFormModel(key, args[1] && get(args[1], value));
});
}
if (autoAddLink) {
const fieldLink = getFormModel('fieldLink') || {};
fieldLink[field] = args[1];
setFormModel('fieldLink', fieldLink);
}
autoSubmit && nextTick(submit as any);
},
onValidateChange: (text: Object | undefined) => {
if (isUndefined(text)) text = {};
validateRef.value = text;
},
};
return {
...propsData,
...on,
...bindValue,
formModel,
};
});
const getComponentsProps = computed(() => {
const { componentProps = {} } = unref(props).schema;
return componentProps;
});
return {
formItemProps,
formProps,
getShow,
getIfShow,
components,
getFormItemDisplay,
getFormItemClass,
getSlots,
formLayout,
};
},
beforeCreate() {
this.$options.components = this.components;
},
});
</script>
<style lang="less" scoped>
.ns-tips {
height: auto;
line-height: 32px;
width: auto;
display: inline-block;
}
</style>

37
lib/component/form/form/form.d.ts vendored Normal file
View File

@@ -0,0 +1,37 @@
import type { RuleObject } from 'ant-design-vue/es/form/interface';
declare global {
type Rule = RuleObject & {
trigger?: 'blur' | 'change' | ['change', 'blur'];
};
interface FormSchema {
field: string;
label?: string;
changeEvent?: string; //表单更新事件名称
valueField?: string;
component?: string; // 不定义,则为隐藏发送参数
rules?: Recordable[];
defaultValue?: any;
componentProps?: any;
formItemProps?: any;
viewOnly?: Boolean; // 是否只展示,不发送参数
ifShow?: Boolean | Function; //dom隐藏
show?: Boolean | Function; //css隐藏
// disabled?: Boolean; //是否禁用 (已废弃、和动态有重复部分)
dynamicDisabled?: Boolean | Function; //是否禁用
fieldMap?: Array<string> | Boolean | Props; //把一个值分割成多个值
keepField?: Boolean; //映射时是否保留原值
defaultParams?: Object; // 默认接口参数
dynamicParams?: String | Array<string> | Recordable | Function; //动态接口参数合并defaultParams赋值给params
requiredParams?: Boolean | String | Array<string> | Recordable;
addModel?: Array<string> | Props; // 额外发送参数例如select中
autoAddLink?: Boolean; //把需要联动的值映射到 formModel.fieldLink.field
displayFormItem?: Boolean; //是否显示formItem (label)
autoLink?: true; //是否使用规则自动绑定
class?: String; //添加额外样式
autoSubmit: Boolean; //是否操作后提交表单
format: Function;
}
}

View File

@@ -0,0 +1,338 @@
<!-- @format -->
<template>
<a-form
class="ns-form"
:class="getFormClass.class"
v-bind="getBindValue"
ref="formElRef"
:model="formModel">
<a-row class="ns-form-body" :justify="getFormClass.justify" :gutter="getFormClass.gutter">
<template v-for="(schema, index) in getSchema" :key="schema.field">
<ns-form-item
:show="expandRef || index < splitNumber"
:span="getComponentSpan(schema)"
:schema="schema"
:index="index"
:formModel="formModel">
<template #[item]="data" v-for="item in Object.keys($slots)">
<slot :name="item" v-bind="data || {}"></slot>
</template>
</ns-form-item>
</template>
<a-col
v-if="
showAction
? expandRef && getSchema.length % splitNumber === 0
: (getSchema.length + 1) % splitNumber === 0
"
:span="getFormClass.span" />
<a-col v-if="showAction" :span="getFormClass.span" class="ns-operate">
<a-button @click="reset">重置</a-button>
<a-button type="primary" html-type="submit" :loading="loading">搜索</a-button>
<a-button
type="link"
class="ns-operate-expand"
@click="expandRef = !expandRef"
v-if="getSchema.length > splitNumber && showExpand">
<template v-if="expandRef">
收起
<UpOutlined />
</template>
<template v-else>
展开
<DownOutlined />
</template>
</a-button>
</a-col>
</a-row>
<!-- <template v-for="(schema, index) in getSchema" :key="schema.field">-->
<!-- <ns-form-item :schema="schema" :index="index" :formModel="formModel">-->
<!-- <template #[item]="data" v-for="item in Object.keys($slots)">-->
<!-- <slot :name="item" v-bind="data || {}"></slot>-->
<!-- </template>-->
<!-- </ns-form-item>-->
<!-- </template>-->
<!-- <a-row-->
<!-- v-if="showAction"-->
<!-- style="text-align: right; margin-left: auto"-->
<!-- class="ns-form-item ns-form-item-op">-->
<!-- <a-col span="24" class="operate">-->
<!-- <a-button @click="reset">重置</a-button>-->
<!-- <a-button style="margin-left: 10px" type="primary" html-type="submit" :loading="loading"-->
<!-- >搜索</a-button-->
<!-- >-->
<!-- </a-col>-->
<!-- </a-row>-->
</a-form>
</template>
<!--suppress TypeScriptCheckImport -->
<script lang="ts">
import { computed, defineComponent, nextTick, provide, ref, toRefs, watch } from 'vue';
import { DownOutlined, UpOutlined } from '@ant-design/icons-vue';
import NsFormItem from '/nerv-lib/component/form/form/form-item.vue';
import { useFormModel } from '/nerv-lib/component/form/form/use-form-model';
import { formConfig } from '/nerv-base/config/form.config';
import { formProps } from '/nerv-lib/component/form/form/props';
import { isBoolean, isFunction } from 'lodash-es';
import FormValidator from 'async-validator';
import { watchDebounced, useElementSize } from '@vueuse/core';
export default defineComponent({
name: 'NsForm',
components: { NsFormItem, DownOutlined, UpOutlined },
props: formProps,
emits: ['finish', 'submit', 'reset'],
setup(props, { attrs, emit }) {
const formElRef = ref<null | Recordable>(null);
const validateResult = ref(false);
const { schemas } = toRefs(props);
const isInitDefaultValueRef = ref(false);
const expandRef = ref(props.expand);
const formModel = computed(() => {
return props.model;
});
const childForms = ref<any[]>([]);
function addChildForm(form: any) {
childForms.value.push(form);
}
let splitNumber = ref(3);
const { width: formWidth } = useElementSize(formElRef);
provide('addChildForm', addChildForm);
const getFormClass = computed(() => {
if (props.formLayout === 'flexVertical') {
return formConfig.formLayout.flexVertical;
}
if (props.formLayout === 'flex') {
return formConfig.formLayout.flex;
}
if (props.formLayout === 'flexv2') {
return formConfig.formLayout.flexv2;
}
return formConfig.formLayout.vertical;
});
const FULL_SPAN_LIST = ['NsChildForm'];
const getComponentSpan = (schema: FormSchema) => {
if (FULL_SPAN_LIST.includes(schema.component || '')) {
return 24;
}
if (schema.class?.includes('ns-form-item-full')) {
return 24;
}
return getFormClass.value.span;
};
provide('formLayout', getFormClass.value);
const getBindValue = computed(() => ({
...getFormClass.value,
...attrs,
...props,
title: '',
onSubmit: submit,
onFinish: finish,
}));
const getSchema = computed((): FormSchema[] => {
const { schemas } = props;
const formSchemas = schemas.filter((schema) => schema.component);
return formSchemas as FormSchema[];
});
watchDebounced(
() => formModel.value,
() => {
const rules = {};
setRules(rules, getSchema.value);
const validator = new FormValidator(rules);
validator
.validate(formModel.value)
.then(() => {
validateResult.value = true;
})
.catch(() => {
validateResult.value = false;
});
},
{
debounce: 100,
deep: true,
},
);
watchDebounced(
() => formWidth.value,
(val) => {
if (val <= 768 && getFormClass.value['sm']) {
getFormClass.value.span = getFormClass.value['sm'];
splitNumber.value = 2;
}
if (val > 768 && getFormClass.value['lg']) {
getFormClass.value.span = getFormClass.value['lg'];
splitNumber.value = 3;
}
},
{
debounce: 100,
deep: true,
},
);
function setRules(rules: Recordable, schemas: any[]) {
schemas.forEach((schema) => {
if (schema.rules) {
const { ifShow } = schema;
let isIfShow = true;
if (isBoolean(ifShow)) {
isIfShow = ifShow;
}
if (isFunction(ifShow)) {
isIfShow = ifShow(formModel.value);
}
// console.log('ifShow', isIfShow);
if (isIfShow) {
rules[schema.field] = schema.rules;
}
}
if (schema.componentProps?.schemas) {
setRules(rules, schema.componentProps.schemas);
}
});
}
const {
handleFormModel,
initFormModel,
resetFormModel,
setFormModel,
unsetFormModel,
getFormModel,
} = useFormModel({
schemas,
formModel,
formElRef,
emit,
});
watch(
() => getSchema.value,
() => {
if (isInitDefaultValueRef.value) {
return;
}
initFormModel();
isInitDefaultValueRef.value = true;
},
{
immediate: true,
deep: true,
},
);
/**
* 数据验证成功后回调
*/
const submit = () => {
emit('submit', formModel.value);
return new Promise((resolve) => {
resolve(formModel.value);
});
};
/**
* 提交表单且数据验证成功后回调事件
*/
function finish() {
const data = handleFormModel();
emit('finish', data);
return new Promise((resolve) => {
resolve(data);
});
}
/**
* 主动执行提交
* @param val
*/
function triggerSubmit(val?: string[]) {
return submit().then(() => {
return nextTick().then(() => {
return new Promise((resolve, reject) => {
(formElRef as Recordable).value
.validate(val)
.then((_) => {
resolve(finish());
})
.catch((e) => {
reject(e);
});
});
});
});
}
/**
* 重置表单
*/
const reset = () => {
resetFormModel();
};
provide('setFormModel', setFormModel);
provide('unsetFormModel', unsetFormModel);
provide('getFormModel', getFormModel);
provide('submit', triggerSubmit);
return {
expandRef,
formElRef,
getBindValue,
getSchema,
formModel,
setFormModel,
getFormClass,
validateResult,
reset,
triggerSubmit,
getComponentSpan,
splitNumber,
finish,
};
},
});
</script>
<style lang="less" scoped>
.ns-form {
.ant-row {
flex: 1;
}
.ns-operate {
margin-bottom: 16px;
text-align: right;
margin-left: auto;
.ns-operate-expand {
display: inline-block;
padding: 4px 2px;
border: unset !important;
.anticon {
margin-left: 4px;
}
&:hover {
border: unset !important;
}
&:focus {
border: unset !important;
}
}
.ant-btn {
margin-left: 6px;
}
}
}
</style>

View File

@@ -0,0 +1,11 @@
import formItem from './form-item.vue';
import childForm from './child-form.vue';
import form from './form.vue';
import type { App } from 'vue';
export const NsForm = function (app: App) {
app.component(form.name, form);
app.component(formItem.name, formItem);
app.component(childForm.name, childForm);
return app;
};

View File

@@ -0,0 +1,20 @@
import { reactive, PropType } from 'vue';
import { PropTypes } from '/nerv-lib/util/type';
export const formProps = {
params: PropTypes.object.def(() => ({})),
showAction: PropTypes.bool.def(false),
// validateState: PropTypes.bool.def(false),
schemas: {
type: Array as PropType<FormSchema[]>,
required: true,
default: () => [],
},
model: PropTypes.object.def(() => reactive({})),
loading: PropTypes.bool.def(false),
formLayout: PropTypes.string.def('flexVertical'),
expand: PropTypes.bool.def(true),
showExpand: PropTypes.bool.def(false),
};

View File

@@ -0,0 +1,215 @@
import type { UnwrapRef, Ref } from 'vue';
import { unref, nextTick, toRaw } from 'vue';
import { get, isArray, isNil, isUndefined, isPlainObject, forEach, isFunction } from 'lodash-es';
import { isDateType, transformDate } from '/nerv-lib/component/form/form-util';
interface useFormModelType {
schemas: Ref<UnwrapRef<FormSchema[]>>;
formModel: Ref<Recordable>;
formElRef: any;
emit: Function;
}
export function useFormModel({ schemas, formModel, formElRef, emit }: useFormModelType) {
/**
* 序列化传参 去除viewOnly单个值转多个时间范围、经纬度)
* @param formSchema
*/
function handleFormModel(formSchema = schemas) {
// console.log('formSchema', formSchema.value, formModel.value);
return unref(formSchema).reduce((prev: Recordable, cur: FormSchema) => {
const { field, fieldMap, keepField, format, addModel = [] } = cur;
if (cur.viewOnly !== true) {
let value = getFormModel(field);
if (isFunction(format)) {
value = format(value);
}
if (cur?.componentProps?.schemas) {
Object.assign(prev, handleFormModel(cur.componentProps.schemas));
} else if (fieldMap && !isNil(value)) {
if (fieldMap === true) {
Object.keys(value).forEach((key: string) => {
Object.assign(prev, { [key]: value[key] });
});
} else if (isArray(fieldMap)) {
if (!isArray(value) && ![null, undefined, ''].includes(value)) {
console.error(`Field value isn't Array`);
} else {
fieldMap.forEach((item: string, index) => {
Object.assign(prev, { [item]: value[index] });
});
}
} else if (isPlainObject(fieldMap)) {
if (!isPlainObject(value) && ![null, undefined, ''].includes(value)) {
console.error(`Field value isn't Object`);
} else {
Object.keys(fieldMap).forEach((key: string) => {
Object.assign(prev, { [key]: get(value, (<Props>fieldMap)[key]) });
});
}
}
//保留原值
if (keepField === true) {
Object.assign(prev, { [field]: value });
}
} else {
Object.assign(prev, { [field]: value });
if (isArray(addModel)) {
addModel.forEach((item: string) => {
Object.assign(prev, { [item]: unref(formModel)[item] });
});
} else {
// @ts-ignore
forEach(addModel as any, (value, key) => {
Object.assign(prev, { [key]: unref(formModel)[key] });
});
}
}
}
return prev;
}, {});
}
/**
* 设置默认值, formModel > defaultValue
*/
function initFormModel() {
unref(schemas).forEach((schema: FormSchema) => {
const { field, component, defaultValue, componentProps } = schema;
if (schema.component) {
if (!isUndefined(defaultValue) && isUndefined(getFormModel(field))) {
if (defaultValue && isDateType(component)) {
setFormModel(
field,
transformDate(component as string, defaultValue, componentProps.valueFormat),
);
} else {
setFormModel(field, defaultValue);
}
} else if (isDateType(component) && !isUndefined(getFormModel(field))) {
setFormModel(
field,
transformDate(component as string, getFormModel(field), componentProps.valueFormat),
);
}
} else {
setFormModel(field, defaultValue);
}
});
}
/**
* 恢复默认值 defaultValue
*/
function resetFormModel() {
Object.keys(formModel.value).forEach((key) => {
unsetFormModel(key);
});
console.log(formModel.value);
unref(schemas).forEach((schema: FormSchema) => {
const { field, component, defaultValue, componentProps } = schema;
setFormModel(field, defaultValue);
if (schema.component) {
if (defaultValue && isDateType(component)) {
setFormModel(
field,
transformDate(component as string, defaultValue, componentProps.valueFormat),
);
} else {
setFormModel(field, defaultValue);
}
} else {
setFormModel(field, defaultValue);
}
});
emit('reset', toRaw(formModel.value));
}
async function validateFields(nameList?: string[] | undefined) {
await nextTick();
return unref(formElRef)?.validateFields(nameList);
}
// function fieldRules(field: string) {
// if (field === 'fieldLink') return undefined;
// console.log('field', field, getNamePath.value);
// return getNamePath.value[field]?.rules || undefined;
// }
// function setNamePath(schemas: FormSchema[], namePathList: Recordable = {}) {
// unref(schemas).forEach((schema: FormSchema) => {
// if (schema.rules) {
// namePathList[schema.field] = {
// state: false,
// rules: schema.rules,
// };
// }
// if (schema?.componentProps?.schemas) {
// setNamePath(schema?.componentProps?.schemas, namePathList);
// }
// });
// console.log('namePathList', namePathList);
// return namePathList;
// }
// const getNamePath = computed(() => {
// return setNamePath(unref(schemas));
// });
/**
* 设置表单值
* @param key
* @param value
*/
function setFormModel(key: string, value?: any) {
if (value === null) {
delete unref(formModel)[key];
} else {
//select allowClear时值被设为undefined
unref(formModel)[key] = value;
}
validateFields([key]).catch(() => {});
// console.log('formModel', key, value, formModel.value);
// if (fieldRules(key)) {
// console.log('getNamePath', getNamePath.value);
// validateFields([key])
// .then((data) => {
// console.log('validateFields then', key, data);
// })
// .catch((e) => {
// console.log('validateFields catch', key, e);
// });
// }
}
/**
* 清除表单值
* @param key
*/
function unsetFormModel(key: string) {
console.log('unsetFormModel', key);
delete unref(formModel)[key];
}
/**
* 获得表单值
* @param key
*/
function getFormModel(key: string) {
return unref(formModel)[key];
}
return {
handleFormModel,
initFormModel,
resetFormModel,
setFormModel,
unsetFormModel,
getFormModel,
};
}

View File

@@ -0,0 +1 @@
export function useForm() {}