You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

351 lines
10 KiB

<!-- @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 || {}" :field="schema.field"></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,
cloneDeep,
} from 'lodash-es';
import { isInputType } from '/nerv-lib/component/form/form-util';
import { useParams } from '/nerv-lib/use/use-params';
enum prefix {
'请选择',
'请输入',
}
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, style },
} = 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,
style,
...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,
label,
dynamicParams,
changeEvent = 'change',
valueField,
addModel = [],
autoAddLink = false,
autoSubmit = false,
componentProps,
} = props.schema;
const isCheck =
component && ['NsSwitch', 'NsCheckbox', 'Switch', 'Checkbox'].includes(component);
const eventKey = `on${upperFirst(changeEvent)}`;
const attr: Recordable = {};
const isInput = isInputType(component);
if (isInput) {
attr.allowClear = true;
}
// const { placeholder } = componentProps;
// // 赋予初始提示符
// componentProps['placeholder'] = placeholder || `${prefix[Number(isInput)]}${label}`;
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,
cloneDeep,
};
},
beforeCreate() {
this.$options.components = this.components;
},
});
</script>
<style lang="less" scoped>
.ns-tips {
height: auto;
line-height: 32px;
width: auto;
display: inline-block;
}
</style>