123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- <template>
- <el-form ref="form" :model="form" :rules="rules" v-bind="options">
- <slot name="pre"></slot>
- <slot>
- <el-form-item
- v-for="(item, index) in fields"
- :key="'form-field-' + index"
- :label="item.field.label"
- :prop="item.field.name"
- :required="item.field.required"
- :rules="item.rules"
- v-bind="item.formOpts"
- v-show="isNew || !item.slots.nonce"
- >
- <slot name="field" v-if="item.slots.ext" v-bind="{ item, form, handleFieldChange, setFieldValue }">
- <span>customEditor</span>
- </slot>
- <naf-input
- v-else
- v-model="form[item.field.name]"
- :disabled="readonly || item.field.readonly || (!isNew && item.field.editable === false)"
- :placeholder="(item.formOpts && item.formOpts.placeholder) || (isNew && item.field.readonly && '--- 系统生成 ---')"
- :dict="item.dict"
- :type="item.formOpts && item.formOpts.inputType"
- v-bind="{ ...item.formOpts, ...mergeLength(item) }"
- @change="handleFieldChange(item.field.name, $event)"
- ></naf-input>
- </el-form-item>
- </slot>
- <slot name="ext" v-bind:form="form"></slot>
- <slot name="submit">
- <el-form-item v-show="!readonly">
- <el-button type="primary" @click="handleSave">{{ closeOnSaved ? '保存并关闭' : '保存' }}</el-button>
- <el-button type="info" @click="$emit('cancel')">取消</el-button>
- </el-form-item>
- </slot>
- </el-form>
- </template>
- <script>
- import { FieldMeta } from './meta-util';
- import NafInput from './naf-input';
- export default {
- name: 'data-form',
- components: {
- NafInput,
- },
- props: {
- data: { type: Object, required: true },
- meta: { type: Array, required: true },
- rules: Object,
- readonly: { type: Boolean, default: false } /* 是否只读 */,
- isNew: { type: Boolean, default: false } /* 是否新创建 */,
- options: Object,
- onlyModified: { type: Boolean, default: false } /** 是否只保存修改字段 */,
- closeOnSaved: { type: Boolean, default: false } /** 保存并关闭 */,
- },
- data() {
- return {
- form: {},
- modified: {},
- };
- },
- mounted() {
- this.reset();
- },
- methods: {
- reset() {
- this.form = { ...this.data };
- },
- handleSave() {
- this.$refs['form'].validate(valid => {
- if (valid) {
- this.$emit('save', {
- isNew: this.isNew,
- isModified: this.isModified,
- data: this.onlyModified ? this.modified : this.form,
- closeOnSaved: this.closeOnSaved,
- });
- } else {
- console.warn('form validate error!!!');
- }
- });
- },
- mergeRules(meta) {
- const rules = meta.rules || [];
- if (meta.pattern) {
- const pattern = this.$policy(meta.pattern);
- if (pattern !== 0) rules.push({ pattern, whitespace: true, message: '请输入正确内容' });
- }
- if (
- meta.field.required &&
- (!this.rules || !this.rules[meta.field.name] || !this.rules[meta.field.name].some(p => p.required)) &&
- (!meta.rules || !meta.rules || !meta.rules.some(p => p.required))
- ) {
- rules.push({ required: true, whitespace: true, message: '不能为空' });
- return rules;
- } else {
- return meta.rules;
- }
- },
- mergeLength(meta) {
- const rules = [...((this.rules && this.rules[meta.field.name]) || []), ...(meta.rules || [])];
- const { max: maxlength, min: minlength } = rules.find(r => r.max || r.min) || {};
- return { maxlength, minlength };
- },
- validateField(payload) {
- this.$refs['form'].validateField(payload);
- },
- handleFieldChange(name, value) {
- console.debug(`field ${name} changed:`, value);
- if (this.data[name] === value) {
- this.$delete(this.modified, name);
- } else {
- this.$set(this.modified, name, value);
- }
- },
- setFieldValue(name, value) {
- this.$set(this.form, name, value);
- this.handleFieldChange(name, value);
- },
- },
- computed: {
- fields() {
- return this.meta
- .map(FieldMeta)
- .filter(p => p.slots.form)
- .sort((a, b) => a.order - b.order || a.index - b.index)
- .map(p => ({
- ...p,
- dict: p.dict || (this.$dict && p.formatter && p.formatter.name === 'dict' && this.$dict(p.formatter.param)),
- rules: this.mergeRules(p),
- }));
- },
- isModified() {
- return this.getModifiedFields.length > 0;
- },
- getModifiedFields() {
- return Object.keys(this.modified);
- },
- },
- };
- </script>
|