UNPKG

vue-ant-patterns

Version:

vue-ant-patterns

505 lines (478 loc) 17 kB
import _mergeJSXProps from 'babel-helper-vue-jsx-merge-props'; import _defineProperty from 'babel-runtime/helpers/defineProperty'; import _typeof from 'babel-runtime/helpers/typeof'; import _extends from 'babel-runtime/helpers/extends'; import PropTypes from 'ant-design-vue/es/_util/vue-types'; import classNames from 'classnames'; import { ColProps } from 'ant-design-vue/es/grid/Col'; import Vue from 'vue'; import isRegExp from 'lodash/isRegExp'; import warning from 'ant-design-vue/es/_util/warning'; import createDOMForm from 'ant-design-vue/es/vc-form/src/createDOMForm'; import createFormField from 'ant-design-vue/es/vc-form/src/createFormField'; import { FIELD_META_PROP, FIELD_DATA_PROP } from './constants'; import { ConfigConsumerProps } from 'ant-design-vue/es/config-provider/configConsumerProps'; import Base from 'ant-design-vue/es/base'; import Row from 'ant-design-vue/es/grid/Row'; import Col from 'ant-design-vue/es/grid/Col'; import resizeObserver from './resizeObserver'; import { initDefaultProps, getComponentFromProp, filterEmpty, getSlotOptions, isValidElement, getAllChildren } from 'ant-design-vue/es/_util/props-util'; import { cloneElement, cloneVNodes } from 'ant-design-vue/es/_util/vnode'; import { Form } from 'ant-design-vue'; import MixinForm from './mixinForm'; export var FormCreateOption = { onFieldsChange: PropTypes.func, onValuesChange: PropTypes.func, mapPropsToFields: PropTypes.func, validateMessages: PropTypes.any, withRef: PropTypes.bool, name: PropTypes.string }; // function create export var WrappedFormUtils = { /** 获取一组输入控件的值,如不传入参数,则获取全部组件的值 */ getFieldsValue: PropTypes.func, /** 获取一个输入控件的值*/ getFieldValue: PropTypes.func, /** 设置一组输入控件的值*/ setFieldsValue: PropTypes.func, /** 设置一组输入控件的值*/ setFields: PropTypes.func, /** 校验并获取一组输入域的值与 Error */ validateFields: PropTypes.func, // validateFields(fieldNames: Array<string>, options: Object, callback: ValidateCallback): void; // validateFields(fieldNames: Array<string>, callback: ValidateCallback): void; // validateFields(options: Object, callback: ValidateCallback): void; // validateFields(callback: ValidateCallback): void; // validateFields(): void; /** 与 `validateFields` 相似,但校验完后,如果校验不通过的菜单域不在可见范围内,则自动滚动进可见范围 */ validateFieldsAndScroll: PropTypes.func, // validateFieldsAndScroll(fieldNames?: Array<string>, options?: Object, callback?: ValidateCallback): void; // validateFieldsAndScroll(fieldNames?: Array<string>, callback?: ValidateCallback): void; // validateFieldsAndScroll(options?: Object, callback?: ValidateCallback): void; // validateFieldsAndScroll(callback?: ValidateCallback): void; // validateFieldsAndScroll(): void; /** 获取某个输入控件的 Error */ getFieldError: PropTypes.func, getFieldsError: PropTypes.func, /** 判断一个输入控件是否在校验状态*/ isFieldValidating: PropTypes.func, isFieldTouched: PropTypes.func, isFieldsTouched: PropTypes.func, /** 重置一组输入控件的值与状态,如不传入参数,则重置所有组件 */ resetFields: PropTypes.func, getFieldDecorator: PropTypes.func }; export var FormProps = { layout: PropTypes.oneOf(['horizontal', 'inline', 'vertical']), labelCol: PropTypes.shape(ColProps).loose, wrapperCol: PropTypes.shape(ColProps).loose, form: PropTypes.object, // onSubmit: React.FormEventHandler<any>; prefixCls: PropTypes.string.def('depot-dform'), hideRequiredMark: PropTypes.bool, autoFormCreate: PropTypes.func, options: PropTypes.object, selfUpdate: PropTypes.bool, colnum: PropTypes.oneOf(['1', '2', '3', 'auto']).def('2'), breakWidth: PropTypes.number.def(800), // form宽度小于多少,水平布局变成垂直布局 openBreakWidth: PropTypes.bool.def(true) // 是否打开断点的开关,默认是打开的 }; export var ValidationRule = { /** validation error message */ message: PropTypes.string, /** built-in validation type, available options: https://github.com/yiminghe/async-validator#type */ type: PropTypes.string, /** indicates whether field is required */ required: PropTypes.boolean, /** treat required fields that only contain whitespace as errors */ whitespace: PropTypes.boolean, /** validate the exact length of a field */ len: PropTypes.number, /** validate the min length of a field */ min: PropTypes.number, /** validate the max length of a field */ max: PropTypes.number, /** validate the value from a list of possible values */ 'enum': PropTypes.oneOfType([String, PropTypes.arrayOf(String)]), /** validate from a regular expression */ pattern: PropTypes.custom(isRegExp), /** transform a value before validation */ transform: PropTypes.func, /** custom validate function (Note: callback must be called) */ validator: PropTypes.func }; // export type ValidateCallback = (errors: any, values: any) => void; // export type GetFieldDecoratorOptions = { // /** 子节点的值的属性,如 Checkbox 的是 'checked' */ // valuePropName?: string; // /** 子节点的初始值,类型、可选值均由子节点决定 */ // initialValue?: any; // /** 收集子节点的值的时机 */ // trigger?: string; // /** 可以把 onChange 的参数转化为控件的值,例如 DatePicker 可设为:(date, dateString) => dateString */ // getValueFromEvent?: (...args: any[]) => any; // /** Get the component props according to field value. */ // getValueProps?: (value: any) => any; // /** 校验子节点值的时机 */ // validateTrigger?: string | string[]; // /** 校验规则,参见 [async-validator](https://github.com/yiminghe/async-validator) */ // rules?: ValidationRule[]; // /** 是否和其他控件互斥,特别用于 Radio 单选控件 */ // exclusive?: boolean; // /** Normalize value to form component */ // normalize?: (value: any, prevValue: any, allValues: any) => any; // /** Whether stop validate on first rule of error for this field. */ // validateFirst?: boolean; // /** 是否一直保留子节点的信息 */ // preserve?: boolean; // }; var DForm = { name: 'DForm', props: initDefaultProps(FormProps, { layout: 'horizontal', hideRequiredMark: false }), mixins: [MixinForm], DItem: Form.Item, // createFormField: createFormField, // create: (options = {}) => { // return createDOMForm({ // fieldNameProp: 'id', // ...options, // fieldMetaProp: FIELD_META_PROP, // fieldDataProp: FIELD_DATA_PROP, // }); // }, createForm: function createForm(context) { var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var V = Base.Vue || Vue; return new V(Form.create(_extends({}, options, { templateContext: context }))()); }, data: function data() { return { onRef: null, resizeObserver: resizeObserver(), oldLayout: this.$props.layout, // 寸放layout的上一次记录 formLayout: this.$props.layout // from使用的layout }; }, mounted: function mounted() { var _this = this; var openBreakWidth = this.$props.openBreakWidth; if (openBreakWidth) { // 打开断点开关的情况,进行form元素变化的的监听 this.onRef = this.$refs.DFromRef; console.log('mounted,', this.onRef); this.$nextTick(function () { // dom对象发生变化后的操作逻辑赋值给dom对象 _this.onRef.$el.handleResize = _this.handleResize; // 观察的对象 _this.resizeObserver.observe(_this.onRef.$el); }); } }, beforeDestroy: function beforeDestroy() { if (this.resizeObserver) { this.resizeObserver.unobserve(this.onRef.$el); } }, methods: { handleResize: function handleResize(contentRect, ele) { var formWidth = contentRect.width; // form的宽度 var breakWidth = this.$props.breakWidth; // 当宽度小于断点宽度的时候 if (parseInt(formWidth) < breakWidth) { this.formLayout = 'vertical'; // this.colnum = 1; } else { this.formLayout = this.oldLayout; } console.log('szie---', contentRect); }, onSubmit: function onSubmit(e) { var $listeners = this.$listeners; if (!$listeners.submit) { e.preventDefault(); } else { this.$emit('submit', e); } }, /** * @description: 渲染item * @param {*} item * @return {*} */ renderFormItem: function renderFormItem(item) { var h = this.$createElement; var data = item.data; var label = data.attrs.label; var autoField = data.attrs.autoField; var child = null; if (autoField) { // 自定义 child = this.renderFieldType(autoField); label = autoField.label; } else { child = filterEmpty(item.children); child = cloneVNodes(child); // 这里要加,否则在重新render的时候会有警告 } // console.log(child); this.slotDefault = this.decoratorChildren(child); var newColProps = this.setItemCol(item); var formItemProps = { props: _extends({ label: label }, newColProps, this.$attrs) }; return h(Col, [h( 'a-form-item', formItemProps, [this.slotDefault] )]); }, decoratorChildren: function decoratorChildren(vnodes) { var form = this.$props.form; var getFieldDecorator = form.getFieldDecorator; for (var i = 0, len = vnodes.length; i < len; i++) { var vnode = vnodes[i]; if (getSlotOptions(vnode).__ANT_FORM_ITEM) { break; } if (vnode.children) { vnode.children = this.decoratorChildren(cloneVNodes(vnode.children)); } else if (vnode.componentOptions && vnode.componentOptions.children) { vnode.componentOptions.children = this.decoratorChildren(cloneVNodes(vnode.componentOptions.children)); } var option = this.decoratorOption(vnode); if (option && option[0]) { vnodes[i] = getFieldDecorator(option[0], option[1], this)(vnode); } } return vnodes; }, decoratorOption: function decoratorOption(vnode) { if (vnode.data && vnode.data.directives) { var directive = vnode.data.directives.find(function (value) { return value.name === 'decorator'; }); // find(vnode.data.directives, ['name', 'decorator']); warning(!directive || directive && Array.isArray(directive.value), 'Invalid directive: type check failed for directive \'decorator\'. Expected Array, got ' + _typeof(directive ? directive.value : directive) + '. At ' + vnode.tag + '.'); return directive ? directive.value : null; } else { return null; } }, // 组件内部控制label的占比 setItemCol: function setItemCol(item) { var attrs = item.data.attrs; var isOneLine = attrs.isOneLine; var colnum = this.$props.colnum; var formLayout = this.formLayout; // console.log('itemCol', this.$props); // 垂直布局直接返回 if (formLayout === 'vertical') { return { labelCol: {}, wrapperCol: {} }; } if (isOneLine && colnum === '2') { return { labelCol: { xs: { span: 24 }, sm: { span: 4 } }, wrapperCol: { xs: { span: 24 }, sm: { span: 17 } } }; } else if (isOneLine && colnum === '3') { return { labelCol: { xs: { span: 24 }, sm: { span: 3 } }, wrapperCol: { xs: { span: 24 }, sm: { span: 21 } } }; } else if (colnum === '3') { return { labelCol: { xs: { span: 24 }, sm: { span: 10 } }, wrapperCol: { xs: { span: 24 }, sm: { span: 14 } } }; } else { return { labelCol: { xs: { span: 24 }, sm: { span: 8 } }, wrapperCol: { xs: { span: 24 }, sm: { span: 10 } } }; } }, renderFieldType: function renderFieldType(fieldPropertys) { var type = fieldPropertys.type; return this['render$' + type](fieldPropertys); } }, render: function render() { var _classNames, _this2 = this; var h = arguments[0]; var prefixCls = this.prefixCls, hideRequiredMark = this.hideRequiredMark, layout = this.layout, onSubmit = this.onSubmit, $slots = this.$slots, autoFormCreate = this.autoFormCreate, _options = this.options, options = _options === undefined ? {} : _options, colnum = this.colnum, formLayout = this.formLayout; var formClassName = classNames((_classNames = {}, _defineProperty(_classNames, prefixCls + '-horizontal', formLayout === 'horizontal'), _defineProperty(_classNames, prefixCls + '-vertical', formLayout === 'vertical'), _defineProperty(_classNames, prefixCls + '-inline', formLayout === 'inline'), _defineProperty(_classNames, prefixCls + '-hide-required-mark', hideRequiredMark), _classNames)); if (autoFormCreate) { warning(false, '`autoFormCreate` is deprecated. please use `form` instead.'); var DomForm = this.DomForm || createDOMForm(_extends({ fieldNameProp: 'id' }, options, { fieldMetaProp: FIELD_META_PROP, fieldDataProp: FIELD_DATA_PROP, templateContext: this.$vnode.context }))({ provide: function provide() { return { decoratorFormProps: this.$props }; }, data: function data() { return { children: $slots['default'], formClassName: formClassName, submit: onSubmit }; }, created: function created() { autoFormCreate(this.form); }, render: function render() { var h = arguments[0]; var children = this.children, formClassName = this.formClassName, submit = this.submit; return h( 'form', { on: { 'submit': submit }, 'class': formClassName }, [children] ); } }); if (this.domForm) { this.domForm.children = $slots['default']; this.domForm.submit = onSubmit; this.domForm.formClassName = formClassName; } this.DomForm = DomForm; return h(DomForm, { attrs: { wrappedComponentRef: function wrappedComponentRef(inst) { _this2.domForm = inst; } } }); } // 过滤调没用的 var newDefaultSlots = $slots['default'].filter(function (item) { return item.tag !== undefined; }); var rowProps = { props: { gutter: 8 } }; var formProps = { props: _extends({ layout: formLayout }, this.$attrs), 'class': formClassName }; return h( Form, _mergeJSXProps([formProps, { on: { 'submit': onSubmit }, ref: 'DFromRef' }]), [h( Row, rowProps, [newDefaultSlots.map(function (item) { // 判断d-form-item是否有isOneLine的设置, 如果有,独占一行 var data = item.data; var attrs = data.attrs; var isOneLine = attrs.isOneLine; var pop = { formLayout: formLayout }; switch (colnum) { // case 'auto': // pop.props = { // xxl: 8, // xl: 12, // lg: 12, // md: 24, // sm: 24, // xs: 24, // }; // break; case '1': pop.props = { span: 24 / colnum }; break; case '2': pop.props = { span: 24 / colnum }; break; case '3': pop.props = { span: 24 / colnum }; break; default: break; } if (isOneLine) { pop.props = { span: 24 }; } // 控制单独的一个item可以独占一行如textarea return item.tag ? h( Col, pop, [_this2.renderFormItem(item)] ) : ''; })] )] ); } }; export default DForm;