WidgetForm.vue 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. <template>
  2. <div class="widget-form-container" :style="{width: data.config.width, margin: 'auto'}">
  3. <el-form :size="data.config.size" label-suffix=": " :label-position="data.config.labelPosition" :label-width="data.config.labelWidth + 'px'">
  4. <div v-if="data.list.length == 0" class="form-empty">{{$t('fm.description.containerEmpty')}}</div>
  5. <draggable class=""
  6. v-model="data.list"
  7. v-bind="{group:'people', ghostClass: 'ghost',animation: 200, handle: '.drag-widget'}"
  8. @add="handleWidgetAdd"
  9. @update="handleWidgetUpdate"
  10. >
  11. <transition-group name="fade" tag="div" class="widget-form-list" >
  12. <template v-for="(element, index) in data.list" v-if="element && element.key">
  13. <widget-table
  14. v-if="element.type === 'table'"
  15. :key="element.key"
  16. :element="element"
  17. :select.sync="selectWidget"
  18. :index="index" :data="data"
  19. @select-change="handleSelectChange"
  20. >
  21. </widget-table>
  22. <widget-tab-item
  23. v-else-if="element.type === 'tabs'"
  24. :key="element.key"
  25. :element="element"
  26. :select.sync="selectWidget"
  27. :index="index" :data="data"
  28. @select-change="handleSelectChange"
  29. >
  30. </widget-tab-item>
  31. <widget-form-item
  32. v-else-if="element.type !== 'grid'"
  33. :key="element.key"
  34. :element="element"
  35. :select.sync="selectWidget"
  36. :index="index" :data="data"
  37. @select-change="handleSelectChange"
  38. >
  39. </widget-form-item>
  40. <widget-col-item
  41. v-else
  42. :key="element.key"
  43. :element="element"
  44. :select.sync="selectWidget"
  45. :index="index" :data="data"
  46. @select-change="handleSelectChange"
  47. >
  48. </widget-col-item>
  49. </template>
  50. </transition-group>
  51. </draggable>
  52. </el-form>
  53. </div>
  54. </template>
  55. <script>
  56. import Draggable from 'vuedraggable'
  57. import WidgetFormItem from './WidgetFormItem'
  58. import WidgetColItem from './WidgetColItem'
  59. import WidgetTable from './WidgetTable'
  60. import WidgetTabItem from './WidgetTabItem'
  61. import { EventBus } from '../util/event-bus.js'
  62. import _ from 'lodash'
  63. export default {
  64. components: {
  65. Draggable,
  66. WidgetFormItem,
  67. WidgetColItem,
  68. WidgetTable,
  69. WidgetTabItem
  70. },
  71. props: ['data', 'select'],
  72. data () {
  73. return {
  74. selectWidget: this.select
  75. }
  76. },
  77. mounted () {
  78. document.body.ondrop = function (event) {
  79. let isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1
  80. if (isFirefox) {
  81. event.preventDefault()
  82. event.stopPropagation()
  83. }
  84. }
  85. EventBus.$on('on-field-add', item => {
  86. console.log('.....')
  87. console.log(item, this.data, this.select)
  88. const key = new Date().getTime() + ''
  89. let widgetItem = _.cloneDeep({
  90. ...item,
  91. options: {
  92. ...item.options,
  93. remoteFunc: 'func_' + key,
  94. remoteOption: 'option_' + key
  95. },
  96. key,
  97. model: item.type + '_' + key,
  98. rules: []
  99. })
  100. this._addWidget(this.data.list, widgetItem)
  101. this.$nextTick(() => { EventBus.$emit('on-history-add') })
  102. })
  103. },
  104. methods: {
  105. _addWidget (list, widget, isTable = false) {
  106. if (isTable
  107. && (widget.type == 'grid' || widget.type == 'table' || widget.type == 'tabs' || widget.type == 'divider')) {
  108. this.$message.warning(this.$t('fm.message.noPut'))
  109. return false
  110. }
  111. if (this.selectWidget && this.selectWidget.key) {
  112. const index = list.findIndex(item => item.key == this.selectWidget.key)
  113. if (index >= 0) {
  114. list.splice(index + 1, 0, widget)
  115. this.selectWidget = list[index + 1]
  116. } else {
  117. list.forEach(item => {
  118. if (item.type === 'grid') {
  119. item.columns.forEach(column => {
  120. this._addWidget(column.list, widget)
  121. })
  122. }
  123. if (item.type === 'table') {
  124. this._addWidget(item.tableColumns, widget, true)
  125. }
  126. if (item.type === 'tabs') {
  127. item.tabs.forEach(tab => {
  128. this._addWidget(tab.list, widget)
  129. })
  130. }
  131. })
  132. }
  133. } else {
  134. list.push(widget)
  135. this.selectWidget = list[list.length - 1]
  136. }
  137. },
  138. handleWidgetUpdate (evt) {
  139. this.$nextTick(() => { EventBus.$emit('on-history-add') })
  140. },
  141. handleWidgetAdd (evt) {
  142. console.log('add', evt)
  143. console.log('end', evt)
  144. const newIndex = evt.newIndex
  145. const to = evt.to
  146. console.log(to)
  147. //为拖拽到容器的元素添加唯一 key
  148. const key = new Date().getTime() + ''
  149. this.$set(this.data.list, newIndex, {
  150. ...this.data.list[newIndex],
  151. options: {
  152. ...this.data.list[newIndex].options,
  153. remoteFunc: this.data.list[newIndex].options.remoteFunc || 'func_' + key,
  154. remoteOption: this.data.list[newIndex].options.remoteOption || 'option_' + key,
  155. },
  156. key,
  157. // 绑定键值
  158. model: this.data.list[newIndex].model ? this.data.list[newIndex].model : this.data.list[newIndex].type + '_' + key,
  159. rules: this.data.list[newIndex].rules ? [...this.data.list[newIndex].rules] : []
  160. })
  161. this.$set(this.data.list, newIndex, _.cloneDeep(this.data.list[newIndex]))
  162. this.selectWidget = this.data.list[newIndex]
  163. this.$nextTick(() => { EventBus.$emit('on-history-add') })
  164. },
  165. handleWidgetDelete (index) {
  166. if (this.data.list.length - 1 === index) {
  167. if (index === 0) {
  168. this.selectWidget = {}
  169. } else {
  170. this.selectWidget = this.data.list[index - 1]
  171. }
  172. } else {
  173. this.selectWidget = this.data.list[index + 1]
  174. }
  175. this.$nextTick(() => {
  176. this.data.list.splice(index, 1)
  177. this.$nextTick(() => { EventBus.$emit('on-history-add') })
  178. })
  179. },
  180. handleSelectChange (index) {
  181. console.log('select-change', index)
  182. setTimeout(() => {
  183. index >=0 ? (this.selectWidget = this.data.list[index]) : (this.selectWidget = {})
  184. })
  185. }
  186. },
  187. watch: {
  188. select (val) {
  189. this.selectWidget = val
  190. },
  191. selectWidget: {
  192. handler (val) {
  193. this.$emit('update:select', val)
  194. },
  195. deep: true
  196. }
  197. }
  198. }
  199. </script>
  200. <style lang="scss">
  201. .fade-enter-active, .fade-leave-active {
  202. transition: opacity .3s;
  203. }
  204. .fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ {
  205. opacity: 0;
  206. }
  207. </style>