form-dlg.vue 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. <template>
  2. <el-dialog :title="title" :visible="visible" :width="width" :close-on-click-modal="false" @close="$emit('cancel')">
  3. <el-form ref="form" :model="form" :rules="rules" v-bind="options">
  4. <slot>
  5. <el-form-item
  6. v-for="(item, index) in fields"
  7. :key="'form-field-' + index"
  8. :label="item.field.label"
  9. :prop="item.field.name"
  10. :required="item.field.required"
  11. :rules="item.rules"
  12. v-bind="item.formOpts"
  13. >
  14. <naf-input
  15. v-model="form[item.field.name]"
  16. :disabled="readonly || item.field.readonly || (!isNew && item.field.editable === false)"
  17. :placeholder="(item.formOpts && item.formOpts.placeholder) || (isNew && item.field.readonly && '--- 系统生成 ---')"
  18. :dict="item.dict"
  19. :type="item.formOpts && item.formOpts.inputType"
  20. v-bind="mergeLength(item)"
  21. ></naf-input>
  22. </el-form-item>
  23. </slot>
  24. </el-form>
  25. <div slot="footer" class="dialog-footer">
  26. <el-button type="primary" @click="handleSave" :size="options.size" v-show="!readonly">确 定</el-button>
  27. <el-button @click="$emit('cancel')" :size="options.size">取 消</el-button>
  28. </div>
  29. </el-dialog>
  30. </template>
  31. <script>
  32. import { FieldMeta } from './meta-util';
  33. import NafInput from './naf-input';
  34. export default {
  35. name: 'data-dlg',
  36. components: {
  37. NafInput,
  38. },
  39. props: {
  40. data: { type: Object, required: true },
  41. meta: { type: Array, required: true },
  42. rules: Object,
  43. readonly: { type: Boolean, default: false } /* 是否只读 */,
  44. isNew: { type: Boolean, default: false } /* 是否新创建 */,
  45. options: {
  46. type: Object,
  47. default: () => ({ size: 'small' }),
  48. } /* form options */,
  49. width: String,
  50. title: String,
  51. visible: { type: Boolean, default: true },
  52. },
  53. data() {
  54. return {
  55. form: { ...this.data },
  56. };
  57. },
  58. methods: {
  59. handleSave() {
  60. this.$refs['form'].validate(valid => {
  61. if (valid) {
  62. this.$emit('save', { isNew: this.isNew, data: this.form });
  63. } else {
  64. console.warn('form validate error!!!');
  65. }
  66. });
  67. },
  68. mergeRules(meta) {
  69. if (
  70. meta.field.required &&
  71. (!this.rules || !this.rules[meta.field.name] || !this.rules[meta.field.name].some(p => p.required)) &&
  72. (!meta.rules || !meta.rules || !meta.rules.some(p => p.required))
  73. ) {
  74. const rules = meta.rules || [];
  75. rules.push({ required: true, message: '不能为空' });
  76. return rules;
  77. } else {
  78. return meta.rules;
  79. }
  80. },
  81. mergeLength(meta) {
  82. const rules = [...((this.rules && this.rules[meta.field.name]) || []), ...(meta.rules || [])];
  83. const { max, min } = rules.find(r => r.max || r.min) || {};
  84. return { maxlength: max || 48, minlength: min || 0 };
  85. },
  86. },
  87. computed: {
  88. fields() {
  89. return this.meta
  90. .map(FieldMeta)
  91. .filter(p => p.slots.form)
  92. .sort((a, b) => a.order - b.order || a.index - b.index)
  93. .map(p => ({
  94. ...p,
  95. dict: this.$dict && p.formatter && p.formatter.name === 'dict' && this.$dict(p.formatter.param),
  96. rules: this.mergeRules(p),
  97. }));
  98. },
  99. },
  100. };
  101. </script>