<template>
  <div
    class="wrap"
    :class="{ border: drop }"
    @dragover.prevent
    @drop="dropIn"
    style="position: relative"
  >
    <VueDraggable
      type="div"
      class="flex"
      v-if="elementList.length"
      v-model="$store.state.dropIndex.elementList"
      v-bind="{
        sort: drop,
        animation: 500,
      }"
      handle=".move"
      group="componentsGroup"
    >
      <template v-for="(item, index) in elementList">
        <div
          class="chunk"
          :style="{ width: `${item.width}%` }"
          @click.stop="activeBox(item)"
          @mouseenter="mouseenterBox(item)"
          @mouseleave="mouseleaveBox"
          :class="{
            active:
              (drop && item.id == activeInfo.id) ||
              item.id === mouseenterInfo.id,
            move: drop,
            center: item.alignCenter,
          }"
        >
          <i class="el-icon-delete" @click.stop="deleBox(item)" v-if="drop"></i>
          <component :is="item.component" :key="item.key" />
        </div>
      </template>
    </VueDraggable>
    <span class="tip" v-else>从右侧拖入或点击组件进行表单设计..</span>
  </div>
</template>
<script>
import VueDraggable from "vuedraggable";
import { v4 as uuidv4 } from "uuid";
import { mapActions, mapGetters, mapMutations } from "vuex";
export default {
  props: {
    drop: {
      type: Boolean,
      default: false,
    },
  },
  methods: {
    //模块拉入
    dropIn(event) {
      const drop_element = event.dataTransfer.getData("drop_element");
      if (!drop_element) return;
      let tempFlag = this.elementList.some((item) => {
        if (JSON.parse(drop_element).componentName === item.componentName) {
          return true;
        } else {
          return false;
        }
      });
      if (tempFlag) {
        this.$message({
          type: "warning",
          message: "禁止加入相同组件",
        });
        return;
      }
      const dropElement = JSON.parse(drop_element);
      dropElement.id = uuidv4();
      dropElement.key = uuidv4();
      dropElement.component =
        this.$options.components[dropElement.componentName];
      this.updateElementList(dropElement);
    },
    //点击模块
    activeBox(item) {
      if (!this.drop) return;
      this.SET_ACTIONINFO(item);
    },
    //鼠标移入模块
    mouseenterBox(item) {
      if (!this.drop) return;
      this.SET_MOUSEENTERINFO(item);
    },
    //鼠标移出模块
    mouseleaveBox() {
      if (!this.drop) return;
      this.REMOVE_MOUSEENTERINFO();
    },
    //删除模块
    deleBox(item) {
      if (!this.drop) return;
      //需判断删除模块是否为选中模块，如果是则移除选择
      if (item.id === this.activeInfo.id) {
        this.REMOVE_ACTIONINFO({});
      }
      this.REMOVE_ELEMENT_LIST(item);
    },
    ...mapActions("dropIndex", ["updateElementList"]),
    ...mapMutations("dropIndex", [
      "SET_ACTIONINFO",
      "SET_MOUSEENTERINFO",
      "REMOVE_MOUSEENTERINFO",
      "REMOVE_ELEMENT_LIST",
      "REMOVE_ACTIONINFO",
    ]),
  },
  computed: {
    ...mapGetters(["elementList", "activeInfo", "mouseenterInfo"]),
  },
  components: {
    VueDraggable,
  },
};
</script>

<style scoped lang='scss'>
.wrap {
  width: 100%;
  height: 100%;

  background-color: #fafafa;
  overflow-y: auto;
  position: relative;
  > .tip {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    color: #c8b2e6;
    font-size: 24px;
    letter-spacing: 5px;
  }
  > .flex {
    display: flex;
    flex-wrap: wrap;
    > .chunk {
      margin: 10px;
      border: 1px solid transparent;
      position: relative;
      > i {
        cursor: pointer;
        position: absolute;
        top: 0px;
        right: 0px;
        color: red;
        display: none;
      }
    }
    .center {
      margin: 10px auto;
    }
  }
  .active {
    border: 1px dashed #5a9cf8 !important;
    > i {
      display: block !important;
    }
  }
}
.border {
  border: 1px dashed #ccc;
}
.move {
  cursor: move !important;
}
</style>