组件左右拖动

2022-05-06 18:34:39 浏览数 (2)

代码语言:javascript复制
<template>
  <div>
    <div style="display:flex;overflow:hidden;">
      <div class="left" style="width:300px;margin-right:20px;" ref="leftRef">
        <ul @dragstart="handleDragStart">
          <li v-for="(item,index) in componentsList" :key="index"
            :data-index="index" draggable>{{item.componentName}}</li>
        </ul>
      </div>
      <!-- 子元素里面有滚动条 flex:1 overflow:hidden;  或者flex:1;width:0 -->
      <div class="right rightContain"
        style="flex:1;overflow:hidden;;margin-right:20px;flex-shrink:0;"
        ref="rightContain">
        <div style="height:100%;overflow:auto;"
          @drop="handleDrop" @dragover="handelDragover" ref="dragedCon"
          @mousedown="handleMouseDown" @mouseup="handleMouseup">
          <div style="background:#fff;height:100%;width:1600px;position:relative;">
            <img src="../assets/imgs/jiujiangScada.jpg" alt="">
            <component class="commonCom drag"
              v-for="(item,index) in dragedComponents" :key="index"
              :is="item.componentFlag" :style="item.style" :data-index="index"
              @click.native="handleClick"></component>
          </div>
        </div>
      </div>
      <div class="right" style="width:250px;">
        <div>名称-{{label}}</div>
        <div>data-myIndex</div>
        <el-input v-model="myDataIndex"></el-input>
        <div>ID</div>
        <el-input v-model="IDValue"></el-input>
        <el-button @click="save">保存</el-button>
      </div>
    </div>
    <div>
      <el-button type="primary" @click="saveHtml">保存html</el-button>
      <div style="overflow:auto;" id="resultHtml">


      
      </div>
    </div>
  </div>

</template>

<script>
import componentsObj from "@/utils/requireComponents.js";
export default {
  name: "test",
  data() {
    return {
      label:"",
      index: 0,
      currentIndex: "",
      indexArr: [],
      myDataIndex: "",
      IDValue: "",
      timer: null,
      disX: "",
      disY: "",
      positionInfor: [],
      dragedComponents: [],
      componentsList: [
        {
          componentName: "文本组件",
          componentFlag: "MyText",
          style: { left: 0, top: 0 },
        },
        {
          componentName: "按钮组件",
          componentFlag: "Button",
          style: { left: 0, top: 0 },
        },
        {
          componentName: "多内容组件",
          componentFlag: "MoreLineText",
          style: { left: 0, top: 0 },
        },
      ],
    };
  },

  components: componentsObj,
  mounted() {},

  methods: {
    save() {
      console.log(this.currentIndex);
      let index = this.currentIndex;
      console.log(typeof index);
      let element = document.querySelector(`[data-myindex='${index}']`);
      console.log(element);
      element.id = this.IDValue;
    },
    handleClick(e) {
      // console.log(e.target.innerHTML)
      this.label = e.target.innerHTML
      console.log(e.target.getAttribute("data-myindex"));
      let dataMyIndex = e.target.getAttribute("data-myindex");
      if (dataMyIndex) {
        this.currentIndex = dataMyIndex;
        this.myDataIndex = dataMyIndex;
      } else {
        this.index  ;
        e.target.setAttribute("data-myindex", this.index);
        this.currentIndex = this.index;
        this.myDataIndex = this.index;
      }
      this.IDValue = document.querySelector(
        `[data-myindex='${this.currentIndex}']`
      ).id;
      console.log(this.currentIndex);
      // e.target.setAttribute("data-myindex",this.index)
      // e.target.id = "123456"
      // console.log(e.target)
    },
    handleMouseDown(e) {
      var el = e.target;
      while (el && el.classList && !el.classList.contains("drag")) {
        el = el.parentNode;
      }
      console.log(el);

      let rightDisX = e.clientX - el.offsetLeft;
      let rightDisY = e.clientY - el.offsetTop;
      console.log(el.offsetTop);
      document.onmousemove = (e) => {
        let left = e.clientX - rightDisX;
        let top = e.clientY - rightDisY;
        el.style.left = left   "px";
        el.style.top = top   "px";

        console.log(el.dataset.index);
        this.dragedComponents[el.dataset.index].style.left = left   "px";
        this.dragedComponents[el.dataset.index].style.top = top   "px";
        console.log(this.dragedComponents);
      };
      console.log(el.offsetLeft);
    },
    handleMouseup() {
      document.onmousemove = null;
      document.onmouseup = null;
    },
    saveHtml() {
      console.log(document.querySelector(".rightContain").innerHTML.replace(/data-v-bef6da34=""/g,''));
      document.querySelector("#resultHtml").innerHTML =
        document.querySelector(".rightContain").innerHTML.replace('data-v-bef6da34=""','');
    },
    handleDragStart(e) {
      console.log("hi");
      console.log(e.target.dataset.index);
      e.dataTransfer.setData("index", e.target.dataset.index);
      this.disX = e.clientX - this.$refs.leftRef.getBoundingClientRect().left;
      this.disY = e.clientY - this.$refs.leftRef.getBoundingClientRect().top;
      console.log(this.disX);
      console.log(this.disY);
    },
    handelDragover(e) {
      e.preventDefault();
    },
    handleDrop(e) {
      console.log(e.dataTransfer.getData("index"));
      let index = e.dataTransfer.getData("index");
      let component = JSON.parse(JSON.stringify(this.componentsList[index]));
      console.log(this.$refs.dragedCon.scrollLeft);
      let left = e.clientX - this.$refs.dragedCon.getBoundingClientRect().left;
      let top = e.clientY - this.$refs.dragedCon.getBoundingClientRect().top;
      console.log(left);
      console.log(top);
      let scrollLeft = this.$refs.dragedCon.scrollLeft;
      let scrollTop = this.$refs.dragedCon.scrollTop;
      if (scrollLeft > 0) {
        left  = scrollLeft;
      }
      if (scrollTop > 0) {
        top  = scrollTop;
      }
      component.style.left = left - this.disX   "px";
      component.style.top = top - 15   "px";
      console.log(component);
      this.dragedComponents.push(component);

      e.preventDefault();
      e.stopPropagation();
    },
  },
};
</script>

<style scoped>
.left {
  border: 1px solid #ccc;
  height: 500px;
}
.right {
  border: 1px solid #ccc;
  height: 500px;
}
.commonCom {
  position: absolute;
}
</style>

 举例其中的一个组件 MoreLineText.vue

代码语言:javascript复制
<template>
  <ul class="p3 textul">
    <li class="p-title">标题</li>
    <li><span class="title-span">温度 </span><input type="text" class="textbox "
        value="11345566" readonly="readonly"> <span class="unit">℃</span></li>
  </ul>
</template>

批量注册组件 requireComponents.js 

代码语言:javascript复制
let webpackConponents = require.context("../components", true, /(.vue)$/);
console.log(webpackConponents);

let componentsObj = {};
webpackConponents.keys().forEach((key) => {
    console.log(key); // ./requreContext1.vue  ./requreContext2.vue  ./newTest/RequreContext3.vue
    var index = key.lastIndexOf("/")
    let componentName = key.substring(index   1, key.length).replace(/.vue$/, "")
    console.log(componentName)

    // let componentName = key.split("/")[1].replace(/.vue$/, "");
    let componentConfig = webpackConponents(key); //注意不能用[]
    componentsObj[componentName] = componentConfig.default;
   
});

console.log(componentsObj);

export default componentsObj

0 人点赞