GenerateForm.vue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. <template>
  2. <div :style="{width: data.config.width}">
  3. <el-form ref="generateForm"
  4. :key="formKey"
  5. :class="{
  6. [data.config.customClass]: data.config.customClass?true: false,
  7. 'no-label-form': data.config.labelWidth == 0
  8. }"
  9. label-suffix=": "
  10. :size="data.config.size"
  11. :model="models"
  12. :rules="rules"
  13. :label-position="data.config.labelPosition"
  14. :disabled="!edit"
  15. :label-width="data.config.labelWidth + 'px'">
  16. <template v-for="item in data.list">
  17. <generate-col-item
  18. v-if="item.type == 'grid'"
  19. :key="item.key"
  20. :model.sync="models"
  21. :rules="rules"
  22. :element="item"
  23. :remote="remote"
  24. :blanks="blanks"
  25. :display="displayFields"
  26. @input-change="onInputChange"
  27. :edit="edit"
  28. :remote-option="remoteOption"
  29. >
  30. <template v-slot:[blank.name]="scope" v-for="blank in blanks">
  31. <slot :name="blank.name" :model="scope.model"></slot>
  32. </template>
  33. </generate-col-item>
  34. <generate-tab-item
  35. v-else-if="item.type == 'tabs'"
  36. :key="item.key"
  37. :model.sync="models"
  38. :rules="rules"
  39. :element="item"
  40. :remote="remote"
  41. :blanks="blanks"
  42. :display="displayFields"
  43. @input-change="onInputChange"
  44. :edit="edit"
  45. :remote-option="remoteOption"
  46. >
  47. <template v-slot:[blank.name]="scope" v-for="blank in blanks">
  48. <slot :name="blank.name" :model="scope.model"></slot>
  49. </template>
  50. </generate-tab-item>
  51. <generate-form-item
  52. v-else
  53. :key="item.key"
  54. :models.sync="models"
  55. :rules="rules"
  56. :widget="item"
  57. :remote="remote"
  58. :blanks="blanks"
  59. :display="displayFields"
  60. @input-change="onInputChange"
  61. :edit="edit"
  62. :remote-option="remoteOption"
  63. >
  64. <template v-slot:[blank.name]="scope" v-for="blank in blanks">
  65. <slot :name="blank.name" :model="scope.model"></slot>
  66. </template>
  67. </generate-form-item>
  68. </template>
  69. </el-form>
  70. </div>
  71. </template>
  72. <script>
  73. import GenerateFormItem from './GenerateFormItem'
  74. import GenerateColItem from './GenerateColItem'
  75. import GenerateTabItem from './GenerateTabItem'
  76. import {loadJs} from '../util/index.js'
  77. import _ from 'lodash'
  78. export default {
  79. name: 'fm-generate-form',
  80. components: {
  81. GenerateFormItem,
  82. GenerateColItem,
  83. GenerateTabItem
  84. },
  85. props: {
  86. data: {
  87. type: Object,
  88. default: () => ({
  89. "list": [],
  90. "config": {
  91. "labelWidth": 100,
  92. "labelPosition": "right",
  93. "size": "small",
  94. "customClass": "",
  95. "ui": "element",
  96. "layout": "horizontal",
  97. "labelCol": 3
  98. }
  99. })
  100. },
  101. remote: {
  102. type: Object,
  103. default: () => ({})
  104. },
  105. value: {
  106. type: Object,
  107. default: () => ({})
  108. },
  109. edit: {
  110. type: Boolean,
  111. default: true
  112. },
  113. remoteOption: {
  114. type: Object,
  115. default: () => ({})
  116. }
  117. },
  118. data () {
  119. return {
  120. models: {},
  121. rules: {},
  122. blanks: [],
  123. displayFields: {},
  124. dataBindFields: [],
  125. generateShow: false,
  126. resetModels: {},
  127. formKey: new Date().getTime(),
  128. formValue: this.value
  129. }
  130. },
  131. created () {
  132. this._initForm()
  133. },
  134. mounted () {
  135. },
  136. methods: {
  137. _initForm () {
  138. if (Object.keys(this.data).length) {
  139. this.generateModel(this.data.list)
  140. } else {
  141. this.generateModel([])
  142. }
  143. this.resetModels = _.cloneDeep(this.models)
  144. },
  145. generateModel (genList) {
  146. for (let i = 0; i < genList.length; i++) {
  147. if (genList[i].type === 'grid') {
  148. this.displayFields[genList[i].model] = !genList[i].options.hidden
  149. genList[i].columns.forEach(item => {
  150. this.generateModel(item.list)
  151. })
  152. } else if (genList[i].type === 'tabs') {
  153. genList[i].tabs.forEach(item => {
  154. this.generateModel(item.list)
  155. })
  156. this.displayFields[genList[i].model] = !genList[i].options.hidden
  157. } else {
  158. if (Object.keys(this.formValue).indexOf(genList[i].model) >= 0) {
  159. // 处理老版本没有dataBind值的情况,默认绑定数据
  160. if (Object.keys(genList[i].options).indexOf('dataBind') < 0 || genList[i].options.dataBind) {
  161. this.models[genList[i].model] = this.formValue[genList[i].model]
  162. this.dataBindFields.push(genList[i].model)
  163. }
  164. this.displayFields[genList[i].model] = !genList[i].options.hidden
  165. if (genList[i].type === 'blank') {
  166. this.blanks.push({
  167. name: genList[i].model
  168. })
  169. }
  170. } else {
  171. if (genList[i].type === 'blank') {
  172. // bound the default value
  173. if (Object.keys(genList[i].options).indexOf('dataBind') < 0 || genList[i].options.dataBind) {
  174. // this.models[genList[i].model] = genList[i].options.defaultType === 'String' ? '' : (genList[i].options.defaultType === 'Object' ? {} : [])
  175. this.models[genList[i].model] = genList[i].options.defaultType === 'String' ? genList[i].options.defaultValue : (genList[i].options.defaultType === 'Object' ? {} : [])
  176. this.dataBindFields.push(genList[i].model)
  177. }
  178. this.displayFields[genList[i].model] = !genList[i].options.hidden
  179. this.blanks.push({
  180. name: genList[i].model
  181. })
  182. } else {
  183. if (Object.keys(genList[i].options).indexOf('dataBind') < 0 || genList[i].options.dataBind) {
  184. this.models[genList[i].model] = genList[i].type == 'table' ? [] : genList[i].options.defaultValue
  185. this.dataBindFields.push(genList[i].model)
  186. }
  187. this.displayFields[genList[i].model] = !genList[i].options.hidden
  188. }
  189. }
  190. genList[i].tableColumns && genList[i].tableColumns.length && genList[i].tableColumns.forEach(item => {
  191. if (item.type === 'blank') {
  192. this.blanks.push({
  193. name: item.model
  194. })
  195. }
  196. // 处理 rules
  197. if (this.rules[`${genList[i].model}.${item.model}`]) {
  198. this.rules[`${genList[i].model}.${item.model}`] = [
  199. ...this.rules[`${genList[i].model}.${item.model}`],
  200. ...item.rules.map(im => {
  201. if (im.pattern) {
  202. return {...im, pattern: eval(im.pattern)}
  203. } else {
  204. return {...im}
  205. }
  206. })
  207. ]
  208. } else {
  209. this.rules[`${genList[i].model}.${item.model}`] = [
  210. ...item.rules.map(im => {
  211. if (im.pattern) {
  212. return {...im, pattern: eval(im.pattern)}
  213. } else {
  214. return {...im}
  215. }
  216. })
  217. ]
  218. }
  219. })
  220. if (this.rules[genList[i].model]) {
  221. this.rules[genList[i].model] = [...this.rules[genList[i].model], ...genList[i].rules.map(item => {
  222. if (item.pattern) {
  223. return {...item, pattern: eval(item.pattern)}
  224. } else {
  225. return {...item}
  226. }
  227. })]
  228. } else {
  229. this.rules[genList[i].model] = [...genList[i].rules.map(item => {
  230. if (item.pattern) {
  231. return {...item, pattern: eval(item.pattern)}
  232. } else {
  233. return {...item}
  234. }
  235. })]
  236. }
  237. }
  238. }
  239. },
  240. _setDisabled (genList, fields ,disabled) {
  241. for (let i = 0; i < genList.length; i++) {
  242. if (genList[i].type === 'grid') {
  243. genList[i].columns.forEach(item => {
  244. this._setDisabled(item.list, fields, disabled)
  245. })
  246. } else if (genList[i].type === 'tabs') {
  247. genList[i].tabs.forEach(item => {
  248. this._setDisabled(item.list, fields, disabled)
  249. })
  250. } else {
  251. if (fields.indexOf(genList[i].model) >= 0) {
  252. this.$set(genList[i].options, 'disabled', disabled)
  253. }
  254. }
  255. }
  256. },
  257. getData () {
  258. return new Promise((resolve, reject) => {
  259. this.$refs.generateForm.validate(valid => {
  260. if (valid) {
  261. const resData = {}
  262. Object.keys(this.models).forEach(key => {
  263. if (this.displayFields[key] && this.dataBindFields.indexOf(key) >= 0) {
  264. resData[key] = this.models[key]
  265. }
  266. })
  267. resolve(JSON.parse(JSON.stringify(resData)))
  268. resolve(resData)
  269. } else {
  270. reject(new Error(this.$t('fm.message.validError')).message)
  271. }
  272. })
  273. })
  274. },
  275. reset () {
  276. this.setData(_.cloneDeep(this.resetModels))
  277. this.formKey = new Date().getTime()
  278. },
  279. onInputChange (value, field) {
  280. this.$emit('on-change', field, value, this.models)
  281. this.$emit(`on-${field}-change`, value)
  282. },
  283. display (fields) {
  284. Object.keys(this.displayFields).forEach(key => {
  285. if (fields.indexOf(key) >= 0) {
  286. this.$set(this.displayFields, key, true)
  287. }
  288. })
  289. this.displayFields = {...this.displayFields}
  290. },
  291. hide (fields) {
  292. Object.keys(this.displayFields).forEach(key => {
  293. if (fields.indexOf(key) >= 0) {
  294. this.$set(this.displayFields, key, false)
  295. }
  296. })
  297. this.displayFields = {...this.displayFields}
  298. },
  299. disabled (fields, disabled) {
  300. this._setDisabled(this.data.list, fields, disabled)
  301. },
  302. refresh () {
  303. },
  304. setData (value) {
  305. this.models = {...this.models, ...value}
  306. }
  307. },
  308. watch: {
  309. data: {
  310. deep: true,
  311. handler (val) {
  312. this._initForm()
  313. }
  314. },
  315. models: {
  316. deep: true,
  317. handler (val) {
  318. this.formValue = {...val}
  319. }
  320. }
  321. }
  322. }
  323. </script>
  324. <style lang="scss">
  325. </style>