riku
2024-10-24 3d3e7f45086799fdd7a412e2079710a6cdf8dc2b
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
<template>
  <el-form
    :inline="false"
    :model="formObj"
    ref="formRef"
    :rules="allRules"
    label-position="right"
    label-width="150px"
  >
    <slot name="form-item" :formObj="formObj"></slot>
    <el-form-item v-if="showButtons">
      <el-button
        :disabled="!edit"
        type="primary"
        @click="onSubmit"
        :loading="loading"
        >{{ submitName }}</el-button
      >
      <el-button v-if="useReset" :disabled="!edit" @click="onReset"
        >重置</el-button
      >
      <el-button v-if="useCancel" @click="onCancel">取消</el-button>
    </el-form-item>
  </el-form>
</template>
 
<script setup>
/**
 * 表单编辑基类
 * 使用说明:
 * 在插槽<slot name="form-item">中添加自定义<el-form-item>元素
 * 可传入初始表单数据formInfo,表单校验规则rules
 * 实现submit和cancel触发函数
 */
import {
  defineProps,
  defineEmits,
  reactive,
  ref,
  watch,
  computed,
  defineExpose
} from 'vue';
import { useFormConfirm } from '@/composables/formConfirm';
 
const props = defineProps({
  //表单基本信息
  formInfo: {
    type: Object,
    default: () => {
      return {};
    }
  },
  //表单检验规则
  rules: Object,
  showButtons: {
    type: Boolean,
    default: true
  },
  submitName: {
    type: String,
    default: '提交'
  },
  //取消按钮是否可用
  useCancel: Boolean,
  //重置按钮是否可用
  useReset: Boolean,
  //触发重置
  doClear: Boolean,
  //通知编辑状态
  isEdit: Boolean
});
 
//触发函数,提交和取消
const emit = defineEmits(['submit', 'cancel', 'update:isEdit']);
 
const baseRules = reactive({
  _usertype: [
    {
      required: true,
      message: '用户类型不能为空',
      trigger: 'change'
    }
  ],
  _locations: [
    {
      required: true,
      message: '行政区划不能为空',
      trigger: 'change'
    }
  ],
  _scenetype: [
    {
      required: true,
      message: '场景类型不能为空',
      trigger: 'change'
    }
  ]
});
 
//表单操作函数
const { formObj, formRef, edit, onSubmit, onCancel, onReset, clear } =
  useFormConfirm({
    submit: {
      do: submit
    },
    cancel: {
      do: cancel
    }
  });
 
//加载状态
const loading = ref(false);
 
//提交按钮触发
function submit() {
  loading.value = true;
  return new Promise((resolve, reject) => {
    emit(
      'submit',
      formObj,
      () => {
        resolve();
      },
      (err) => {
        reject(err ? err : '');
      }
    );
  }).finally(() => (loading.value = false));
}
 
//取消按钮触发
function cancel() {
  emit('cancel');
}
 
const allRules = computed(() => {
  return { ...baseRules, ...props.rules };
});
 
//监听表单初始数据传入
watch(
  () => props.formInfo,
  (nValue) => {
    formObj.value = nValue;
  },
  { deep: false, immediate: true }
);
 
//监听表单重置功能触发
watch(
  () => props.doClear,
  (nValue) => {
    if (nValue) {
      clear();
    }
  }
);
 
//监听表单编辑状态
watch(
  () => props.isEdit,
  (nV, oV) => {
    if (nV != oV) {
      edit.value = nV;
    }
  },
  { immediate: true }
);
watch(edit, (nV, oV) => {
  if (nV != oV) {
    emit('update:isEdit', nV);
  }
});
 
defineExpose({ formObj, onSubmit, onCancel, onReset });
</script>
 
<style scoped></style>