index.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467
  1. <!--
  2. * @Description: 传入record数据,通过判断record.type,来渲染对应的组件
  3. * @Author: kcz
  4. * @Date: 2020-01-02 22:41:48
  5. * @LastEditors: kcz
  6. * @LastEditTime: 2021-05-28 00:59:02
  7. -->
  8. <template>
  9. <a-form-item
  10. v-if="
  11. [
  12. 'input',
  13. 'textarea',
  14. 'date',
  15. 'time',
  16. 'number',
  17. 'radio',
  18. 'checkbox',
  19. 'select',
  20. 'rate',
  21. 'switch',
  22. 'slider',
  23. 'uploadImg',
  24. 'uploadFile',
  25. 'cascader',
  26. 'treeSelect'
  27. ].includes(record.type)
  28. "
  29. :label-col="
  30. formConfig.layout === 'horizontal'
  31. ? formConfig.labelLayout === 'flex'
  32. ? { style: `width:${formConfig.labelWidth}px` }
  33. : formConfig.labelCol
  34. : {}
  35. "
  36. :wrapper-col="
  37. formConfig.layout === 'horizontal'
  38. ? formConfig.labelLayout === 'flex'
  39. ? { style: 'width:auto;flex:1' }
  40. : formConfig.wrapperCol
  41. : {}
  42. "
  43. :style="
  44. formConfig.layout === 'horizontal' && formConfig.labelLayout === 'flex'
  45. ? { display: 'flex' }
  46. : {}
  47. "
  48. >
  49. <span slot="label">
  50. <a-tooltip>
  51. <span v-text="record.label"></span>
  52. <span v-if="record.help" slot="title" v-html="record.help"></span>
  53. <a-icon
  54. v-if="record.help"
  55. class="question-circle"
  56. type="question-circle-o"
  57. />
  58. </a-tooltip>
  59. </span>
  60. <!-- 多行文本 -->
  61. <a-textarea
  62. :style="`width:${record.options.width}`"
  63. v-if="record.type === 'textarea'"
  64. :autoSize="{
  65. minRows: record.options.minRows,
  66. maxRows: record.options.maxRows
  67. }"
  68. :disabled="disabled || record.options.disabled"
  69. :placeholder="record.options.placeholder"
  70. :allowClear="record.options.clearable"
  71. :maxLength="record.options.maxLength"
  72. :rows="4"
  73. @change="handleChange($event.target.value, record.model)"
  74. v-decorator="[
  75. record.model, // input 的 name
  76. {
  77. initialValue: record.options.defaultValue, // 默认值
  78. rules: record.rules // 验证规则
  79. }
  80. ]"
  81. />
  82. <!-- 单选框 -->
  83. <a-radio-group
  84. v-else-if="record.type === 'radio'"
  85. :options="
  86. !record.options.dynamic
  87. ? record.options.options
  88. : dynamicData[record.options.dynamicKey]
  89. ? dynamicData[record.options.dynamicKey]
  90. : []
  91. "
  92. :disabled="disabled || record.options.disabled"
  93. :placeholder="record.options.placeholder"
  94. @change="handleChange($event.target.value, record.model)"
  95. v-decorator="[
  96. record.model,
  97. {
  98. initialValue: record.options.defaultValue,
  99. rules: record.rules
  100. }
  101. ]"
  102. />
  103. <!-- 多选框 -->
  104. <a-checkbox-group
  105. v-else-if="record.type === 'checkbox'"
  106. :options="
  107. !record.options.dynamic
  108. ? record.options.options
  109. : dynamicData[record.options.dynamicKey]
  110. ? dynamicData[record.options.dynamicKey]
  111. : []
  112. "
  113. :disabled="disabled || record.options.disabled"
  114. :placeholder="record.options.placeholder"
  115. @change="handleChange($event, record.model)"
  116. v-decorator="[
  117. record.model,
  118. {
  119. initialValue: record.options.defaultValue,
  120. rules: record.rules
  121. }
  122. ]"
  123. />
  124. <!-- 开关 -->
  125. <a-switch
  126. v-else-if="record.type === 'switch'"
  127. :disabled="disabled || record.options.disabled"
  128. @change="handleChange($event, record.model)"
  129. v-decorator="[
  130. record.model,
  131. {
  132. initialValue: record.options.defaultValue,
  133. valuePropName: 'checked',
  134. rules: record.rules
  135. }
  136. ]"
  137. />
  138. <!-- 滑块 -->
  139. <div
  140. v-else-if="record.type === 'slider'"
  141. :style="`width:${record.options.width}`"
  142. class="slider-box"
  143. >
  144. <div class="slider">
  145. <a-slider
  146. :disabled="disabled || record.options.disabled"
  147. :min="record.options.min"
  148. :max="record.options.max"
  149. :step="record.options.step"
  150. @change="handleChange($event, record.model)"
  151. v-decorator="[
  152. record.model,
  153. {
  154. initialValue: record.options.defaultValue,
  155. rules: record.rules
  156. }
  157. ]"
  158. />
  159. </div>
  160. <div class="number" v-if="record.options.showInput">
  161. <a-input-number
  162. style="width: 100%"
  163. :disabled="disabled || record.options.disabled"
  164. :min="record.options.min"
  165. :max="record.options.max"
  166. :step="record.options.step"
  167. @change="handleChange($event, record.model)"
  168. v-decorator="[
  169. record.model,
  170. {
  171. initialValue: record.options.defaultValue,
  172. rules: [
  173. {
  174. validator: (rule, value, callback) => {
  175. if (
  176. record.options.step &&
  177. value % record.options.step !== 0
  178. ) {
  179. callback('输入值必须是步长的倍数');
  180. }
  181. callback();
  182. }
  183. }
  184. ]
  185. }
  186. ]"
  187. />
  188. </div>
  189. </div>
  190. <component
  191. v-else
  192. :style="`width:${record.options.width}`"
  193. v-bind="componentOption"
  194. :min="
  195. record.options.min || record.options.min === 0
  196. ? record.options.min
  197. : -Infinity
  198. "
  199. :max="
  200. record.options.max || record.options.max === 0
  201. ? record.options.max
  202. : Infinity
  203. "
  204. :precision="
  205. record.options.precision > 50 ||
  206. (!record.options.precision && record.options.precision !== 0)
  207. ? null
  208. : record.options.precision
  209. "
  210. :parentDisabled="disabled || record.options.disabled"
  211. :disabled="disabled || record.options.disabled"
  212. :record="record"
  213. :config="config"
  214. :filterOption="
  215. record.options.showSearch
  216. ? (inputValue, option) => {
  217. return (
  218. option.componentOptions.children[0].text
  219. .toLowerCase()
  220. .indexOf(inputValue.toLowerCase()) >= 0
  221. );
  222. }
  223. : false
  224. "
  225. :allowClear="record.options.clearable"
  226. :dynamicData="dynamicData"
  227. :treeData="
  228. !record.options.dynamic
  229. ? record.options.options
  230. : dynamicData[record.options.dynamicKey]
  231. ? dynamicData[record.options.dynamicKey]
  232. : []
  233. "
  234. :options="
  235. !record.options.dynamic
  236. ? record.options.options
  237. : dynamicData[record.options.dynamicKey]
  238. ? dynamicData[record.options.dynamicKey]
  239. : []
  240. "
  241. :mode="record.options.multiple ? 'multiple' : ''"
  242. @change="handleChange($event, record.model)"
  243. v-decorator="[
  244. record.model, // input 的 name
  245. {
  246. initialValue: record.options.defaultValue, // 默认值
  247. rules: record.rules // 验证规则
  248. }
  249. ]"
  250. :is="componentItem"
  251. ></component>
  252. </a-form-item>
  253. <!-- 可隐藏label -->
  254. <a-form-item
  255. v-else-if="['batch', 'editor', 'selectInputList'].includes(record.type)"
  256. :label="!record.options.showLabel ? '' : record.label"
  257. :label-col="
  258. formConfig.layout === 'horizontal' && record.options.showLabel
  259. ? formConfig.labelLayout === 'flex'
  260. ? { style: `width:${formConfig.labelWidth}px` }
  261. : formConfig.labelCol
  262. : {}
  263. "
  264. :wrapper-col="
  265. formConfig.layout === 'horizontal' && record.options.showLabel
  266. ? formConfig.labelLayout === 'flex'
  267. ? { style: 'width:auto;flex:1' }
  268. : formConfig.wrapperCol
  269. : {}
  270. "
  271. :style="
  272. formConfig.layout === 'horizontal' &&
  273. formConfig.labelLayout === 'flex' &&
  274. record.options.showLabel
  275. ? { display: 'flex' }
  276. : {}
  277. "
  278. >
  279. <component
  280. :ref="['batch', 'selectInputList'].includes(record.type) && 'KBatch'"
  281. :style="`width:${record.options.width}`"
  282. v-bind="componentOption"
  283. :record="record"
  284. :config="config"
  285. :parentDisabled="disabled || record.options.disabled"
  286. :disabled="disabled || record.options.disabled"
  287. :dynamicData="dynamicData"
  288. @change="handleChange($event, record.model)"
  289. v-decorator="[
  290. record.model, // input 的 name
  291. {
  292. initialValue: record.options.defaultValue, // 默认值
  293. rules: record.rules // 验证规则
  294. }
  295. ]"
  296. :is="componentItem"
  297. ></component>
  298. </a-form-item>
  299. <!-- button按钮 -->
  300. <a-form-item v-else-if="record.type === 'button'">
  301. <a-button
  302. :disabled="disabled || record.options.disabled"
  303. @click="
  304. record.options.handle === 'submit'
  305. ? false
  306. : record.options.handle === 'reset'
  307. ? $emit('handleReset')
  308. : dynamicData[record.options.dynamicFun]
  309. ? dynamicData[record.options.dynamicFun]()
  310. : false
  311. "
  312. :type="record.options.type"
  313. :html-type="record.options.handle === 'submit' ? 'submit' : undefined"
  314. v-text="record.label"
  315. ></a-button>
  316. </a-form-item>
  317. <!-- alert提示 -->
  318. <a-form-item v-else-if="record.type === 'alert'">
  319. <a-alert
  320. :message="record.label"
  321. :description="record.options.description"
  322. :type="record.options.type"
  323. :showIcon="record.options.showIcon"
  324. :closable="record.options.closable"
  325. :banner="record.options.banner"
  326. />
  327. </a-form-item>
  328. <!-- 文本 -->
  329. <a-form-item v-else-if="record.type === 'text'">
  330. <div :style="{ textAlign: record.options.textAlign }">
  331. <label
  332. :class="{ 'ant-form-item-required': record.options.showRequiredMark }"
  333. :style="{
  334. fontFamily: record.options.fontFamily,
  335. fontSize: record.options.fontSize,
  336. color: record.options.color
  337. }"
  338. v-text="record.label"
  339. ></label>
  340. </div>
  341. </a-form-item>
  342. <!-- html -->
  343. <div
  344. v-else-if="record.type === 'html'"
  345. v-html="record.options.defaultValue"
  346. ></div>
  347. <!-- 自定义组件 -->
  348. <customComponent
  349. v-else-if="customList.includes(record.type)"
  350. :record="record"
  351. :disabled="disabled"
  352. :dynamicData="dynamicData"
  353. @change="handleChange($event, record.model)"
  354. :formConfig="formConfig"
  355. />
  356. <div v-else>
  357. <!-- 分割线 -->
  358. <a-divider
  359. v-if="
  360. record.type === 'divider' &&
  361. record.label !== '' &&
  362. record.options.orientation
  363. "
  364. :orientation="record.options.orientation"
  365. >{{ record.label }}</a-divider
  366. >
  367. <a-divider v-else-if="record.type === 'divider' && record.label !== ''">{{
  368. record.label
  369. }}</a-divider>
  370. <a-divider v-else-if="record.type === 'divider' && record.label === ''" />
  371. </div>
  372. </template>
  373. <script>
  374. /*
  375. * author kcz
  376. * date 2019-11-20
  377. */
  378. // import moment from "moment";
  379. import customComponent from "./customComponent";
  380. import ComponentArray from "../core/components_use";
  381. const _ = require("lodash/object");
  382. export default {
  383. name: "KFormItem",
  384. props: {
  385. // 表单数组
  386. record: {
  387. type: Object,
  388. required: true
  389. },
  390. // form-item 宽度配置
  391. formConfig: {
  392. type: Object,
  393. required: true
  394. },
  395. config: {
  396. type: Object,
  397. default: () => ({})
  398. },
  399. dynamicData: {
  400. type: Object,
  401. default: () => ({})
  402. },
  403. disabled: {
  404. type: Boolean,
  405. default: false
  406. }
  407. },
  408. components: {
  409. customComponent
  410. },
  411. computed: {
  412. customList() {
  413. if (window.$customComponentList) {
  414. return window.$customComponentList.map(item => item.type);
  415. } else {
  416. return [];
  417. }
  418. },
  419. /**
  420. * @description: 输出对应组件
  421. * @param {*}
  422. * @return {*} component
  423. */
  424. componentItem() {
  425. return ComponentArray[this.record.type];
  426. },
  427. componentOption() {
  428. return _.omit(this.record.options, ["defaultValue", "disabled"]);
  429. }
  430. },
  431. methods: {
  432. validationSubform() {
  433. // 验证动态表格
  434. if (!this.$refs.KBatch) return true;
  435. return this.$refs.KBatch.validationSubform();
  436. },
  437. handleChange(e, key) {
  438. let value = e;
  439. if (e && e.target) {
  440. value = e.target.value;
  441. }
  442. // 传递change事件
  443. this.$emit("change", value, key);
  444. }
  445. }
  446. };
  447. </script>
  448. <style lang="less" scoped>
  449. .slider-box {
  450. display: flex;
  451. > .slider {
  452. flex: 1;
  453. margin-right: 16px;
  454. }
  455. > .number {
  456. width: 70px;
  457. }
  458. }
  459. .anticon.anticon-question-circle-o {
  460. margin-left: 5px;
  461. }
  462. </style>