app-form-item.tsx 4.7 KB
import { Vue, Component, Prop, Watch } from 'vue-property-decorator';
import './app-form-item.less';

@Component({})
export default class AppFormItem extends Vue {

    /**
     * 名称
     *
     * @type {string}
     * @memberof AppFormItem
     */
    @Prop() public caption!: string;

    /**
     * 错误信息
     *
     * @type {string}
     * @memberof AppFormItem
     */
    @Prop() public error?: string;

    /**
     * 标签位置
     *
     * @type {(string | 'BOTTOM' | 'LEFT' | 'NONE' | 'RIGHT' | 'TOP')}
     * @memberof AppFormItem
     */
    @Prop() public labelPos?: string | 'BOTTOM' | 'LEFT' | 'NONE' | 'RIGHT' | 'TOP';

    /**
     * 标签宽度
     *
     * @type {number}
     * @memberof AppFormItem
     */
    @Prop({}) public labelWidth!: number;

    /**
     * 是否显示标题
     *
     * @type {boolean}
     * @memberof AppFormItem
     */
    @Prop() public isShowCaption?: boolean;

    /**
     * 标签是否空白
     *
     * @type {boolean}
     * @memberof AppFormItem
     */
    @Prop() public isEmptyCaption?: boolean;

    /**
     * 表单项名称
     *
     * @type {string}
     * @memberof AppFormItem
     */
    @Prop() public name!: string;

    /**
     * 内置样式
     *
     * @type {string}
     * @memberof AppFormItem
     */
    @Prop() public uiStyle?: string;

    /**
     * 表单项值规则
     *
     * @type {string}
     * @memberof AppFormItem
     */
    @Prop() public itemRules!: string;

    /**
     * 值规则数组
     *
     * @type {any[]}
     * @memberof AppFormItem
     */
    public rules: any[] = [];

    /**
     * 是否必填
     *
     * @type {boolean}
     * @memberof AppFormItem
     */
    public required: boolean = false;

    /**
     * 表单项值规则监控
     *
     * @param {*} newVal
     * @param {*} oldVal
     * @memberof AppFormItem
     */
    @Watch('itemRules')
    onItemRulesChange(newVal: any, oldVal: any) {
        if (newVal) {
            try {
                this.rules = [];
                const _rules: any[] = JSON.parse(newVal);
                this.rules = [..._rules];
                this.rules.some((rule: any) => {
                    if (rule.hasOwnProperty('required')) {
                        this.required = rule.required;
                        return true;
                    }
                    return false;
                });
            } catch (error) {
            }
        }
    }

    /**
     * 计算样式
     *
     * @readonly
     * @type {string []}
     * @memberof AppFormItem
     */
    get classes(): string[] {
        return [
            'app-form-item',
            Object.is(this.labelPos, 'TOP') ? 'app-form-item-label-top' : ''
        ];
    }

    /**
     * vue 生命周期
     *
     * @memberof AppFormItem
     */
    public mounted() {
        if (this.itemRules) {
            try {
                const _rules: any[] = JSON.parse(this.itemRules);
                this.rules = [..._rules];
                this.rules.some((rule: any) => {
                    if (rule.hasOwnProperty('required')) {
                        this.required = rule.required;
                        return true;
                    }
                    return false;
                });
            } catch (error) {
            }
        }
    }

    /**
     * 绘制内容
     *
     * @returns
     * @memberof AppFormItem
     */
    public render() {
        if (Object.is(this.uiStyle, 'STYLE2')) {
            return (
                <app-form-item2
                    caption={this.caption}
                    error={this.error}
                    labelPos={this.labelPos}
                    labelWidth={this.labelWidth}
                    isShowCaption={this.isShowCaption}
                    isEmptyCaption={this.isEmptyCaption}
                    name={this.name}
                    uiStyle={this.uiStyle}
                    itemRules={this.itemRules}>
                    {this.$slots.default}
                </app-form-item2>
            );
        } else {
            return (
                <form-item
                    prop={this.name}
                    error={this.error}
                    required={this.required}
                    rules={this.rules}
                    class={this.classes}
                    label-width={this.isShowCaption ? !Object.is(this.labelPos, 'TOP') ? this.labelWidth : null : 0}>
                    {
                        this.isShowCaption && this.labelWidth > 0 ?
                            <span slot='label'>
                                {this.isEmptyCaption ? '' : this.caption}
                            </span>
                            : ''
                    }
                    {this.$slots.default}
                </form-item>
            );
        }
    }
}