WidgetCollapseLayout.vue 8.02 KB
<template>
  <div
    class="widget-form-item"
    @click.stop="handleSelectWidget(index)"
    :class="{active: selectWidgetItem&&selectWidgetItem.key == element.key}"
  >
    <div
      class="drag-widget"
      title="拖拽"
      v-if="selectWidgetItem&&selectWidgetItem.key == element.key"
    >
      <i class="icon-drag"></i>
    </div>
    <div class="widget-view-action" v-if="selectWidgetItem&&selectWidgetItem.key == element.key">
      <i
        class="icon-application-delete del-icon"
        title="删除"
        @click.stop="handleWidgetDelete(index)"
      ></i>
    </div>
    <el-collapse
      class="widget-col"
      v-if="element && element.key"
      type="flex"
      v-model="activeNames"
    >
      <el-collapse-item
        v-for="(col, colIndex) in element.columns"
        :key="colIndex"
        :title="col.span"
        :name="col.idKey"
      >
        <draggable
          v-model="col.list"
          :no-transition-on-drag="true"
          v-bind="{
            group: 'form',
            ghostClass: 'ghost',
            animation: 200,
            handle: '.drag-widget'
          }"
          @start="handleMoveStart"
          @add="handleWidgetColAdd($event, element, colIndex)"
        >
          <transition-group name="fade" tag="div" class="widget-col-list">
            <template v-for="(el, i) in col.list.filter(c => c.key)">
              <widget-grid-layout
                v-if="el.ctrlType == 'grid'"
                :key="el.key"
                :data.sync="col"
                :select="selectWidget"
                :selectWidgetList.sync="selectWidgetList"
                :index="i"
                :element="el"
              />
              <widget-table-layout
                v-else-if="el.ctrlType == 'tab'"
                :key="el.key"
                :data.sync="col"
                :select="selectWidget"
                :selectWidgetList.sync="selectWidgetList"
                :index="i"
                :element="el"
              />
              <widget-subtable-layout
                v-else-if="el.ctrlType == 'subtable'"
                :key="el.key"
                :data.sync="col"
                :select="selectWidget"
                :selectWidgetList.sync="selectWidgetList"
                :index="i"
                :element.sync="el"
              />
              <widget-subdiv-layout
                v-else-if="el.ctrlType == 'subDiv'"
                :key="el.key"
                :data.sync="col"
                :select="selectWidget"
                :selectWidgetList.sync="selectWidgetList"
                :index="i"
                :element.sync="el"
              />
              <widget-hottable-layout
                v-else-if="el.ctrlType == 'hottable'"
                :key="el.key"
                :data.sync="col"
                :selectWidgetList.sync="selectWidgetList"
                :index="i"
                :element.sync="el"
              />
              <widget-main-table-layout
                v-else-if="el.ctrlType == 'table'"
                :key="el.key"
                :data.sync="col"
                :select="selectWidget"
                :selectWidgetList.sync="selectWidgetList"
                :index="i"
                :element.sync="el"
              />
              <widget-form-item
                v-else
                :key="el.key"
                :element="el"
                :select="selectWidgetItem"
                :selectWidgetList.sync="selectWidgetList"
                :index="i"
                :data.sync="col"
              ></widget-form-item>
            </template>
          </transition-group>
        </draggable>
      </el-collapse-item>
    </el-collapse>
  </div>
</template>
<script>
import Draggable from 'vuedraggable'
import WidgetFormItem from '@/components/form/WidgetFormItem.vue'
import WidgetGridLayout from '@/components/form/WidgetGridLayout.vue'
import WidgetTableLayout from '@/components/form/WidgetTableLayout.vue'
import WidgetSubtableLayout from '@/components/form/WidgetSubtableLayout.vue'
import WidgetSubdivLayout from '@/components/form/WidgetSubDivLayout.vue'
import WidgetHottableLayout from '@/components/form/WidgetHottableLayout.vue'
import WidgetMainTableLayout from '@/components/form/WidgetMainTableLayout.vue'
import controlsApi from '@/api/controlsConfig.js'
import deepmerge from 'deepmerge'
import {mapState, mapMutations} from 'vuex'
import updateSelectControl from '@/mixins/updateSelectControl.js'
export default {
  name: 'widget-collapse-layout',
  components: {
    Draggable,
    WidgetFormItem,
    WidgetGridLayout,
    WidgetTableLayout,
    WidgetSubdivLayout,
    WidgetSubtableLayout,
    WidgetHottableLayout,
    WidgetMainTableLayout
  },
  mixins: [updateSelectControl],
  props: ['element', 'select', 'index', 'data', 'selectWidgetList'],
  data() {
    return {}
  },
  computed: {
    ...mapState('form', ['selectWidget']),
    activeNames: {
      get: function() {
        var obj = []
        this.element.columns.forEach(item => {
          obj.push(item.idKey)
        })
        this.$emit('get-collapse-active-name', obj)
        return obj
      },
      set: function(val) {
        this.$emit('get-collapse-active-name', val)
      }
    }
  },

  methods: {
    ...mapMutations({
      setSelectWidget: 'form/setSelectWidget' // 设置当前选中控件
    }),
    handleMoveStart: function(evt) {
      // 新增控件时  将控件属性切断联系
      evt.item._underlying_vm_ = deepmerge({}, evt.item._underlying_vm_, {
        clone: true
      })
      const key =
        Date.parse(new Date()) + '_' + Math.ceil(Math.random() * 99999)
      evt.item._underlying_vm_.key = key

      evt.item._data_vm_=deepmerge({}, this.data.list, {
        clone: true
      })
      evt.item._p_vm_=this.data
    },
    handleSelectWidget(index) {
      this.setSelectWidget(this.data.list[index])
    },
    handleWidgetColAdd($event, row, colIndex) {
      const newIndex = $event.newIndex
      const oldIndex = $event.oldIndex
      const item = $event.item

      // 防止布局元素的嵌套拖拽
      if (
        item.className.indexOf('data-grid') >= 0 ||
        item.innerText == '分页符'
      ) {
        // 如果是列表中拖拽的元素需要还原到原来位置
        item.tagName === 'DIV' &&
          this.data.list.splice(
            oldIndex,
            0,
            row.columns[colIndex].list[newIndex]
          )
        row.columns[colIndex].list.splice(newIndex, 1)
        if($event.item._p_vm_){
          $event.item._p_vm_.list=$event.item._data_vm_
        }
        if (item.innerText == '分页符') {
          this.$message.warning('折叠面板中不允许再拖入分页布局')
        }
        return false
      }
      if (item.innerText != 'tab布局') {
        if(!controlsApi.handleLayoutComponents(
          this,
          row,
          row.columns[colIndex].list,
          newIndex
        )){
          if($event.item._p_vm_){
            $event.item._p_vm_.list=$event.item._data_vm_
          }
          return false
        }
      }
      this.setSelectWidget(row.columns[colIndex].list[newIndex])
    },
    handleWidgetDelete(index) {
      if (this.data.list.length - 1 === index) {
        if (index === 0) {
          this.setSelectWidget({options: {validateType: ''}})
        } else {
          this.setSelectWidget(this.data.list[index - 1])
        }
      } else {
        this.setSelectWidget(this.data.list[index + 1])
      }

      this.$nextTick(() => {
        this.data.list.splice(index, 1)
      })
    }
  }
}
</script>
<style lang="scss" scoped>
@import '@/assets/css/form-editor.scss';

.widget-col {
  padding-bottom: 0;
  padding: 15px 5px;
}

.active {
  outline: 2px solid $--form-design-active-color;
}

.el-col {
  min-height: 50px;
}

.widget-col-list {
  min-height: 50px;
  border: 1px solid #ededed;
}

div.widget-view-action {
  .del-icon {
    width: 20px;
    margin-left: 12px;
  }
}

div.widget-view-action i.icon-trash {
  margin: 0 10px;
}

div.drag-widget {
  // border-color: $--form-design-active-color;
}

div.drag-widget i.icon-drag {
  color: #fff;
}
</style>