index.vue 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. <template>
  2. <a-config-provider :locale="locale">
  3. <a-form
  4. v-if="
  5. typeof value.list !== 'undefined' && typeof value.config !== 'undefined'
  6. "
  7. class="k-form-build-9136076486841527"
  8. :layout="value.config.layout"
  9. :hideRequiredMark="value.config.hideRequiredMark"
  10. :form="form"
  11. @submit="handleSubmit"
  12. :style="value.config.customStyle"
  13. >
  14. <buildBlocks
  15. ref="buildBlocks"
  16. @handleReset="reset"
  17. v-for="(record, index) in value.list"
  18. :record="record"
  19. :dynamicData="getDynamicData"
  20. :config="config"
  21. :disabled="disabled"
  22. :formConfig="value.config"
  23. :validatorError="validatorError"
  24. :key="index"
  25. @change="handleChange"
  26. />
  27. </a-form>
  28. </a-config-provider>
  29. </template>
  30. <script>
  31. /*
  32. * author kcz
  33. * date 2019-11-20
  34. * description 将json数据构建成表单
  35. */
  36. import buildBlocks from "./buildBlocks";
  37. import zhCN from "ant-design-vue/lib/locale-provider/zh_CN";
  38. // import moment from "moment";
  39. export default {
  40. name: "KFormBuild",
  41. data() {
  42. return {
  43. locale: zhCN,
  44. form: this.$form.createForm(this),
  45. validatorError: {},
  46. defaultDynamicData: {}
  47. };
  48. },
  49. // props: ["value", "dynamicData"],
  50. props: {
  51. value: {
  52. type: Object,
  53. required: true
  54. },
  55. dynamicData: {
  56. type: Object,
  57. default: () => {
  58. return {};
  59. }
  60. },
  61. config: {
  62. type: Object,
  63. default: () => ({})
  64. },
  65. disabled: {
  66. type: Boolean,
  67. default: false
  68. },
  69. outputString: {
  70. type: Boolean,
  71. default: false
  72. },
  73. defaultValue: {
  74. type: Object,
  75. default: () => ({})
  76. }
  77. },
  78. components: {
  79. buildBlocks
  80. },
  81. computed: {
  82. getDynamicData() {
  83. return typeof this.dynamicData === "object" &&
  84. Object.keys(this.dynamicData).length
  85. ? this.dynamicData
  86. : window.$kfb_dynamicData || {};
  87. }
  88. },
  89. methods: {
  90. // moment,
  91. handleSubmit(e) {
  92. // 提交按钮触发,并触发submit函数,返回getData函数
  93. e.preventDefault();
  94. this.$emit("submit", this.getData);
  95. },
  96. reset() {
  97. // 重置表单
  98. this.form.resetFields();
  99. },
  100. getData() {
  101. // 提交函数,提供父级组件调用
  102. return new Promise((resolve, reject) => {
  103. try {
  104. this.form.validateFields((err, values) => {
  105. if (err) {
  106. reject(err);
  107. /**
  108. * @author: lizhichao<meteoroc@outlook.com>
  109. * @Description: 多容器校验时,提供error返回给多容器进行判断。
  110. */
  111. this.validatorError = err;
  112. return;
  113. }
  114. this.validatorError = {};
  115. this.$refs.buildBlocks.forEach(item => {
  116. if (!item.validationSubform()) {
  117. reject(err);
  118. }
  119. });
  120. if (this.outputString) {
  121. // 需要所有value转成字符串
  122. for (const key in values) {
  123. const type = typeof values[key];
  124. if (type === "string" || type === "undefined") {
  125. continue;
  126. } else if (type === "object") {
  127. values[key] = `k-form-design#${type}#${JSON.stringify(
  128. values[key]
  129. )}`;
  130. } else {
  131. values[key] = `k-form-design#${type}#${String(values[key])}`;
  132. }
  133. }
  134. resolve(values);
  135. } else {
  136. resolve(values);
  137. }
  138. });
  139. } catch (err) {
  140. console.error(err);
  141. reject(err);
  142. }
  143. });
  144. },
  145. setData(json) {
  146. return new Promise((resolve, reject) => {
  147. try {
  148. if (this.outputString) {
  149. // 将非string数据还原
  150. for (const key in json) {
  151. if (!json[key].startsWith("k-form-design#")) {
  152. continue;
  153. }
  154. const array = json[key].split("#");
  155. if (array[1] === "object") {
  156. json[key] = JSON.parse(array[2]);
  157. } else if (array[1] === "number") {
  158. json[key] = Number(array[2]);
  159. } else if (array[1] === "boolean") {
  160. json[key] = Boolean(array[2]);
  161. }
  162. }
  163. this.form.setFieldsValue(json);
  164. } else {
  165. this.form.setFieldsValue(json);
  166. }
  167. resolve(true);
  168. } catch (err) {
  169. console.error(err);
  170. reject(err);
  171. }
  172. });
  173. },
  174. // 批量设置某个option的值
  175. setOptions(fields, optionName, value) {
  176. fields = new Set(fields);
  177. // 递归遍历控件树
  178. const traverse = array => {
  179. array.forEach(element => {
  180. if (fields.has(element.model)) {
  181. this.$set(element.options, optionName, value);
  182. }
  183. if (element.type === "grid" || element.type === "tabs") {
  184. // 栅格布局 and 标签页
  185. element.columns.forEach(item => {
  186. traverse(item.list);
  187. });
  188. } else if (element.type === "card" || element.type === "batch") {
  189. // 卡片布局 and 动态表格
  190. traverse(element.list);
  191. } else if (element.type === "table") {
  192. // 表格布局
  193. element.trs.forEach(item => {
  194. item.tds.forEach(val => {
  195. traverse(val.list);
  196. });
  197. });
  198. }
  199. });
  200. };
  201. traverse(this.value.list);
  202. },
  203. // 隐藏表单字段
  204. hide(fields) {
  205. this.setOptions(fields, "hidden", true);
  206. },
  207. // 显示表单字段
  208. show(fields) {
  209. this.setOptions(fields, "hidden", false);
  210. },
  211. // 禁用表单字段
  212. disable(fields) {
  213. this.setOptions(fields, "disabled", true);
  214. },
  215. // 启用表单字段
  216. enable(fields) {
  217. this.setOptions(fields, "disabled", false);
  218. },
  219. handleChange(value, key) {
  220. // 触发change事件
  221. this.$emit("change", value, key);
  222. }
  223. },
  224. mounted() {
  225. this.$nextTick(() => {
  226. this.setData(this.defaultValue);
  227. });
  228. }
  229. };
  230. </script>