FormComponentPanel.vue 3.8 KB
Newer Older
W
wwsheng009 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
<!--
 * @Description: 中间表单布局面板
 * https://github.com/SortableJS/vue.draggable.next/issues/138
-->
<template>
  <div class="form-panel v-form-container">
    <Empty
      class="empty-text"
      v-show="formConfig.schemas.length === 0"
      description="从左侧选择控件添加"
    />
    <Form v-bind="formConfig">
      <div class="draggable-box">
        <draggable
          class="list-main ant-row"
          group="form-draggable"
          :component-data="{ name: 'list', tag: 'div', type: 'transition-group' }"
          ghostClass="moving"
          :animation="180"
          handle=".drag-move"
          v-model="formConfig.schemas"
          item-key="key"
          @add="addItem"
          @start="handleDragStart"
        >
          <template #item="{ element }">
            <LayoutItem
              class="drag-move"
              :schema="element"
              :data="formConfig"
              :current-item="formConfig.currentItem || {}"
            />
          </template>
        </draggable>
      </div>
    </Form>
  </div>
</template>
<script lang="ts">
  import draggable from 'vuedraggable';
  import LayoutItem from '../components/LayoutItem.vue';
V
vben 已提交
42
  import { defineComponent, computed } from 'vue';
W
wwsheng009 已提交
43 44 45 46 47 48 49 50 51 52 53 54 55 56
  import { cloneDeep } from 'lodash-es';
  import { useFormDesignState } from '../../../hooks/useFormDesignState';
  import { Form, Empty } from 'ant-design-vue';

  export default defineComponent({
    name: 'FormComponentPanel',
    components: {
      LayoutItem,
      draggable,
      Form,
      Empty,
    },
    emits: ['handleSetSelectItem'],
    setup(_, { emit }) {
V
vben 已提交
57
      const { formConfig } = useFormDesignState();
W
wwsheng009 已提交
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96

      /**
       * 拖拽完成事件
       * @param newIndex
       */
      const addItem = ({ newIndex }: any) => {
        formConfig.value.schemas = formConfig.value.schemas || [];

        const schemas = formConfig.value.schemas;
        schemas[newIndex] = cloneDeep(schemas[newIndex]);
        emit('handleSetSelectItem', schemas[newIndex]);
      };

      /**
       * 拖拽开始事件
       * @param e {Object} 事件对象
       */
      const handleDragStart = (e: any) => {
        emit('handleSetSelectItem', formConfig.value.schemas[e.oldIndex]);
      };

      // 获取祖先组件传递的currentItem

      // 计算布局元素,水平模式下为ACol,非水平模式下为div
      const layoutTag = computed(() => {
        return formConfig.value.layout === 'horizontal' ? 'Col' : 'div';
      });

      return {
        addItem,
        handleDragStart,
        formConfig,
        layoutTag,
      };
    },
  });
</script>

<style lang="less" scoped>
V
vben 已提交
97 98
  @import url('../styles/variable.less');
  @import url('../styles/drag.less');
W
wwsheng009 已提交
99 100 101 102 103 104 105 106

  .v-form-container {
    // 内联布局样式
    .ant-form-inline {
      .list-main {
        display: flex;
        flex-wrap: wrap;
        align-content: flex-start;
V
vben 已提交
107
        justify-content: flex-start;
W
wwsheng009 已提交
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126

        .layout-width {
          width: 100%;
        }
      }

      .ant-form-item-control-wrapper {
        min-width: 175px !important;
      }
    }
  }

  .form-panel {
    position: relative;
    height: 100%;

    .empty-text {
      position: absolute;
      z-index: 100;
V
vben 已提交
127 128 129 130
      inset: -10% 0 0;
      height: 150px;
      margin: auto;
      color: #aaa;
W
wwsheng009 已提交
131 132 133 134 135 136
    }

    .draggable-box {
      // width: 100%;
      .drag-move {
        min-height: 62px;
V
vben 已提交
137
        cursor: move;
W
wwsheng009 已提交
138 139 140 141
      }

      .list-main {
        height: 100%;
V
vben 已提交
142
        overflow: auto;
W
wwsheng009 已提交
143 144 145 146 147 148 149 150 151 152 153 154
        // 列表动画
        .list-enter-active {
          transition: all 0.5s;
        }

        .list-leave-active {
          transition: all 0.3s;
        }

        .list-enter,
        .list-leave-to {
          transform: translateX(-100px);
V
vben 已提交
155
          opacity: 0;
W
wwsheng009 已提交
156 157 158 159 160 161 162 163 164
        }

        .list-enter {
          height: 30px;
        }
      }
    }
  }
</style>