GenerateElementItem.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431
  1. <template>
  2. <span>
  3. <template v-if="widget.type == 'blank'">
  4. <div :style="{width: isTable ? '100%' : widget.options.width}">
  5. <slot :name="widget.model" :model="dataModels"></slot>
  6. </div>
  7. </template>
  8. <template v-if="widget.type == 'component'">
  9. <div :style="{width: isTable ? '100%' : widget.options.width}">
  10. <component :is="`component-${widget.key}-${key}`" :key="key" v-model="dataModel"></component>
  11. </div>
  12. </template>
  13. <template v-if="widget.type == 'custom'">
  14. <div :style="{width: isTable ? '100%' : widget.options.width}">
  15. <component
  16. :is="widget.el"
  17. v-model="dataModel"
  18. :width="widget.options.width"
  19. :height="widget.options.height"
  20. :placeholder="widget.options.placeholder"
  21. :readonly="widget.options.readonly"
  22. :disabled="!edit || widget.options.disabled"
  23. :editable="widget.options.editable"
  24. :clearable="widget.options.clearable"
  25. ></component>
  26. </div>
  27. </template>
  28. <template v-if="widget.type == 'input'" >
  29. <el-input
  30. v-if="widget.options.dataType == 'number' || widget.options.dataType == 'integer' || widget.options.dataType == 'float'"
  31. type="number"
  32. v-model.number="dataModel"
  33. :disabled="!edit || widget.options.disabled"
  34. :placeholder="widget.options.placeholder"
  35. :show-password="widget.options.showPassword"
  36. :style="{width: isTable ? '100%' : widget.options.width}"
  37. ></el-input>
  38. <el-input
  39. v-else
  40. :type="widget.options.dataType"
  41. v-model="dataModel"
  42. :disabled="!edit || widget.options.disabled"
  43. :placeholder="widget.options.placeholder"
  44. :show-password="widget.options.showPassword"
  45. :style="{width: isTable ? '100%' : widget.options.width}"
  46. ></el-input>
  47. </template>
  48. <template v-if="widget.type == 'textarea'">
  49. <el-input type="textarea" :rows="5"
  50. v-model="dataModel"
  51. :disabled="!edit || widget.options.disabled"
  52. :placeholder="widget.options.placeholder"
  53. :style="{width: isTable ? '100%' : widget.options.width}"
  54. ></el-input>
  55. </template>
  56. <template v-if="widget.type == 'number'">
  57. <el-input-number
  58. v-model="dataModel"
  59. :style="{width: isTable ? '100%' : widget.options.width}"
  60. :step="widget.options.step"
  61. controls-position="right"
  62. :disabled="!edit || widget.options.disabled"
  63. :min="widget.options.min"
  64. :max="widget.options.max"
  65. ></el-input-number>
  66. </template>
  67. <template v-if="widget.type == 'radio'">
  68. <el-radio-group v-model="dataModel"
  69. :style="{width: isTable ? '100%' : widget.options.width}"
  70. :disabled="!edit || widget.options.disabled"
  71. >
  72. <el-radio
  73. :style="{display: widget.options.inline ? 'inline-block' : 'block'}"
  74. :label="item.value" v-for="(item, index) in (widget.options.remote ? remoteOptions : widget.options.options)" :key="index"
  75. >
  76. <template v-if="widget.options.remote">{{item.label}}</template>
  77. <template v-else>{{widget.options.showLabel ? item.label : item.value}}</template>
  78. </el-radio>
  79. </el-radio-group>
  80. </template>
  81. <template v-if="widget.type == 'checkbox'">
  82. <el-checkbox-group v-model="dataModel"
  83. :style="{width: isTable ? '100%' : widget.options.width}"
  84. :disabled="!edit || widget.options.disabled"
  85. >
  86. <el-checkbox
  87. :style="{display: widget.options.inline ? 'inline-block' : 'block'}"
  88. :label="item.value" v-for="(item, index) in (widget.options.remote ? remoteOptions : widget.options.options)" :key="index"
  89. >
  90. <template v-if="widget.options.remote">{{item.label}}</template>
  91. <template v-else>{{widget.options.showLabel ? item.label : item.value}}</template>
  92. </el-checkbox>
  93. </el-checkbox-group>
  94. </template>
  95. <template v-if="widget.type == 'time'">
  96. <el-time-picker
  97. v-model="dataModel"
  98. :is-range="widget.options.isRange"
  99. :placeholder="widget.options.placeholder"
  100. :start-placeholder="widget.options.startPlaceholder"
  101. :end-placeholder="widget.options.endPlaceholder"
  102. :readonly="widget.options.readonly"
  103. :disabled="!edit || widget.options.disabled"
  104. :editable="widget.options.editable"
  105. :clearable="widget.options.clearable"
  106. :arrowControl="widget.options.arrowControl"
  107. :value-format="widget.options.format"
  108. :style="{width: isTable ? '100%' : widget.options.width}"
  109. >
  110. </el-time-picker>
  111. </template>
  112. <template v-if="widget.type=='date'">
  113. <el-date-picker
  114. v-model="dataModel"
  115. :type="widget.options.type"
  116. :placeholder="widget.options.placeholder"
  117. :start-placeholder="widget.options.startPlaceholder"
  118. :end-placeholder="widget.options.endPlaceholder"
  119. :readonly="widget.options.readonly"
  120. :disabled="!edit || widget.options.disabled"
  121. :editable="widget.options.editable"
  122. :clearable="widget.options.clearable"
  123. :value-format="widget.options.timestamp ? 'timestamp' : widget.options.format"
  124. :format="widget.options.format"
  125. :style="{width: isTable ? '100%' : widget.options.width}"
  126. >
  127. </el-date-picker>
  128. </template>
  129. <template v-if="widget.type =='rate'">
  130. <el-rate v-model="dataModel"
  131. :max="widget.options.max"
  132. :disabled="!edit || widget.options.disabled"
  133. :allow-half="widget.options.allowHalf"
  134. :show-score="widget.options.showScore"
  135. ></el-rate>
  136. </template>
  137. <template v-if="widget.type == 'color'">
  138. <el-color-picker
  139. v-model="dataModel"
  140. :disabled="!edit || widget.options.disabled"
  141. :show-alpha="widget.options.showAlpha"
  142. ></el-color-picker>
  143. </template>
  144. <template v-if="widget.type == 'select'">
  145. <el-select
  146. v-model="dataModel"
  147. :disabled="!edit || widget.options.disabled"
  148. :multiple="widget.options.multiple"
  149. :clearable="widget.options.clearable"
  150. :placeholder="widget.options.placeholder"
  151. :style="{width: isTable ? '100%' : widget.options.width}"
  152. :filterable="widget.options.filterable"
  153. >
  154. <el-option v-for="item in (widget.options.remote ? remoteOptions : widget.options.options)" :key="item.value" :value="item.value" :label="widget.options.showLabel || widget.options.remote?item.label:item.value"></el-option>
  155. </el-select>
  156. </template>
  157. <template v-if="widget.type=='switch'">
  158. <el-switch
  159. v-model="dataModel"
  160. :disabled="!edit || widget.options.disabled"
  161. >
  162. </el-switch>
  163. </template>
  164. <template v-if="widget.type=='slider'">
  165. <el-slider
  166. v-model="dataModel"
  167. :min="widget.options.min"
  168. :max="widget.options.max"
  169. :disabled="!edit || widget.options.disabled"
  170. :step="widget.options.step"
  171. :show-input="widget.options.showInput"
  172. :range="widget.options.range"
  173. :style="{width: isTable ? '100%' : widget.options.width}"
  174. ></el-slider>
  175. </template>
  176. <template v-if="widget.type=='imgupload'">
  177. <fm-upload
  178. v-model="dataModel"
  179. :disabled="!edit || widget.options.disabled"
  180. :readonly="widget.options.readonly"
  181. :style="{'width': isTable ? '100%' : widget.options.width}"
  182. :width="widget.options.size.width"
  183. :height="widget.options.size.height"
  184. :token="widget.options.token"
  185. :domain="widget.options.domain"
  186. :multiple="widget.options.multiple"
  187. :limit="widget.options.limit"
  188. :is-qiniu="widget.options.isQiniu"
  189. :is-delete="widget.options.isDelete"
  190. :min="widget.options.min"
  191. :is-edit="widget.options.isEdit"
  192. :action="widget.options.action"
  193. :headers="widget.options.headers || []"
  194. >
  195. </fm-upload>
  196. </template>
  197. <template v-if="widget.type == 'editor'">
  198. <fm-editor
  199. v-model="dataModel"
  200. :sty="{width: isTable ? '100%' : widget.options.width, cursor: (!edit || widget.options.disabled) ? 'no-drop' : '', backgroundColor: (!edit || widget.options.disabled) ? '#F5F7FA' : ''}"
  201. :toolbar="widget.options.customToolbar"
  202. :disabled="!edit || widget.options.disabled"
  203. >
  204. </fm-editor>
  205. </template>
  206. <template v-if="widget.type == 'cascader'">
  207. <el-cascader
  208. v-model="dataModel"
  209. :disabled="!edit || widget.options.disabled"
  210. :clearable="widget.options.clearable"
  211. :placeholder="widget.options.placeholder"
  212. :style="{width: isTable ? '100%' : widget.options.width}"
  213. :options="remoteOptions"
  214. >
  215. </el-cascader>
  216. </template>
  217. <template v-if="widget.type == 'text'">
  218. <span>{{dataModel}}</span>
  219. </template>
  220. <template v-if="widget.type == 'html'">
  221. <span v-html="dataModel"></span>
  222. </template>
  223. <template v-if="widget.type == 'table'">
  224. <fm-form-table
  225. :value="dataModel"
  226. :columns="widget.tableColumns"
  227. :models="dataModels"
  228. :remote="remote"
  229. :blanks="blanks"
  230. :disabled="!edit || widget.options.disabled"
  231. :rules="rules"
  232. :name="widget.model"
  233. :remote-option="remoteOption"
  234. >
  235. <template v-slot:[blank.name]="scope" v-for="blank in blanks">
  236. <slot :name="blank.name" :model="scope.model"></slot>
  237. </template>
  238. </fm-form-table>
  239. </template>
  240. <template v-if="widget.type == 'fileupload'">
  241. <fm-file-upload
  242. v-model="dataModel"
  243. :disabled="!edit || widget.options.disabled"
  244. :style="{'width': isTable ? '100%' : widget.options.width}"
  245. :token="widget.options.token"
  246. :domain="widget.options.domain"
  247. :multiple="widget.options.multiple"
  248. :limit="widget.options.limit"
  249. :is-qiniu="widget.options.isQiniu"
  250. :min="widget.options.min"
  251. :action="widget.options.action"
  252. :tip="widget.options.tip"
  253. :headers="widget.options.headers || []"
  254. >
  255. </fm-file-upload>
  256. </template>
  257. </span>
  258. </template>
  259. <script>
  260. import FmUpload from './Upload'
  261. import FmFormTable from './FormTable'
  262. import FmFileUpload from './Upload/file'
  263. import FmEditor from './Editor'
  264. import Vue from 'vue'
  265. export default {
  266. name: 'generate-element-item',
  267. components: {
  268. FmUpload,
  269. FmFormTable,
  270. FmFileUpload,
  271. FmEditor
  272. },
  273. props: ['widget', 'value', 'models', 'remote', 'isTable', 'blanks', 'disabled', 'edit', 'remoteOption', 'rules'],
  274. data () {
  275. return {
  276. dataModel: this.value,
  277. dataModels: {...this.models},
  278. remoteOptions: [],
  279. key: new Date().getTime()
  280. }
  281. },
  282. created () {
  283. this.remoteOptions = []
  284. if (this.widget.options.remote
  285. && (Object.keys(this.widget.options).indexOf('remoteType') >= 0 ? this.widget.options.remoteType == 'func' : true)
  286. && this.remote[this.widget.options.remoteFunc]) {
  287. this.remote[this.widget.options.remoteFunc]((data) => {
  288. this.loadOptions(data)
  289. })
  290. }
  291. if (this.widget.options.remote
  292. && this.widget.options.remoteType == 'option'
  293. && this.remoteOption[this.widget.options.remoteOption]) {
  294. this.loadOptions(this.remoteOption[this.widget.options.remoteOption])
  295. }
  296. if ((this.widget.type === 'imgupload' || this.widget.type === 'fileupload') && this.widget.options.isQiniu) {
  297. !this.widget.options.token && this.remote[this.widget.options.tokenFunc]((data) => {
  298. this.widget.options.token = data
  299. })
  300. }
  301. if (this.widget.type == 'component') {
  302. Vue.component(`component-${this.widget.key}-${this.key}`, {
  303. template: `<span>${this.widget.options.template}</span>`,
  304. props: ['value'],
  305. data: () => ({
  306. dataModel: this.value
  307. }),
  308. watch: {
  309. dataModel (val) {
  310. if (this.ui == 'antd') {
  311. EventBus.$emit('on-field-change', this.$attrs.id, val)
  312. } else {
  313. this.$emit('input', val)
  314. }
  315. },
  316. value (val) {
  317. this.dataModel = val
  318. }
  319. }
  320. })
  321. }
  322. },
  323. methods: {
  324. loadOptions (data) {
  325. this.remoteOptions = data.map(item => {
  326. if (this.widget.options.props.children && this.widget.options.props.children.length && Object.keys(item).includes(this.widget.options.props.children)) {
  327. return {
  328. value: item[this.widget.options.props.value],
  329. label: item[this.widget.options.props.label],
  330. children: this.processRemoteProps(item[this.widget.options.props.children], this.widget.options.props)
  331. }
  332. } else {
  333. return {
  334. value: item[this.widget.options.props.value],
  335. label: item[this.widget.options.props.label]
  336. }
  337. }
  338. })
  339. },
  340. processRemoteProps (children, props) {
  341. if (children && children.length) {
  342. return children.map(item => {
  343. if (this.processRemoteProps(item[props.children], props).length) {
  344. return {
  345. value: item[props.value],
  346. label: item[props.label],
  347. children: this.processRemoteProps(item[props.children], props)
  348. }
  349. } else{
  350. return {
  351. value: item[props.value],
  352. label: item[props.label],
  353. }
  354. }
  355. })
  356. } else {
  357. return []
  358. }
  359. }
  360. },
  361. watch: {
  362. value (val) {
  363. this.dataModel = val
  364. },
  365. models: {
  366. deep: true,
  367. handler (val) {
  368. this.dataModels = {...val}
  369. }
  370. },
  371. dataModel (val) {
  372. this.$emit('input', val)
  373. },
  374. dataModels: {
  375. deep: true,
  376. handler (val) {
  377. this.$emit('input', val[this.widget.model])
  378. }
  379. },
  380. 'remoteOption': {
  381. deep: 'true',
  382. handler: function (val) {
  383. if (Object.keys(this.remoteOption).indexOf(this.widget.options.remoteOption) >= 0
  384. && this.widget.options.remote
  385. && this.widget.options.remoteType == 'option'
  386. ) {
  387. this.loadOptions(this.remoteOption[this.widget.options.remoteOption])
  388. }
  389. }
  390. }
  391. }
  392. }
  393. </script>