vue拖拽组件开发

vue拖拽组件开发


创建临时vue项目

先查看node和npm版本,怎么安装就不多多bb了

再安装vue-cli

npm install vue-cli -g      //全局安装 vue-cli

检测是否安装成功

vue list

创建项目

vue init webpack  "项目名称"

开始写拖拽组件

组件就暂且命名为 JuDrag吧。然后再在index.vue里面引入,代码如下:

<template>
  <div class="a">
    <ju-drag :post_data="post_data">
      <div
        v-for="item in post_data"
        :key="item.id"
        :id="item.id"
        class="b"
      >{{item.name}}</div>
    </ju-drag>
    <div class="b"></div>
  </div>
</template>

<script>
import JuDrag from "@/components/JuDrag";
export default {
  name: "index",
  components: {
    JuDrag
  },
  data() {
    return {
      post_data: [
        {
          id: 11111,
          name: "第一个块"
        },
        {
          id: 22222,
          name: "第二个块"
        },
        {
          id: 33333,
          name: "第三个块"
        },
        {
          id: 44444,
          name: "第四个块"
        },
        {
          id: 555555,
          name: "第五个块"
        },
        {
          id: 66666,
          name: "第六个块"
        },
        {
          id: 77777,
          name: "第七个块"
        }
      ]
    };
  },
  mounted() {}
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style >
.a {
  width: 200px;
  padding: 10px;
  border: 1px #eee solid;
}

.b {
  margin-bottom: 10px;
  height: 50px;
  background: red;
}
</style>

然后写JuDrag.vue代码

<template>
  <div>
    <slot></slot>
  </div>
</template>

<script>
export default {
  name: "HelloWorld",
  data() {
    return {
      pitch_div_id: "", //正在移动的id
    };
  },
  props: {
    post_data: Array
  },
  mounted() {
    this.post_data.forEach(item => {
      let element = document.getElementById(item.id);
      element.setAttribute("draggable", "true");
      element.style =
        "transition:all 0.5s cubic-bezier(0,0,1,1) 0s;";
      this.addHandler(element);
    });
  },
  methods: {
    dragstart(event) {
      event.dataTransfer.setData("Text", event.target.id);
      event.target.style.opacity = "0.4";
      this.pitch_div_id = event.target.id;
    },
    drag(event) {},
    dragend(event) {
      event.target.style.opacity = "1";
    },
    dragenter(event) {
      if (event.target.id == "") return;
      if (event.target.id == this.pitch_div_id) return;
      let x = "",
        y = "";
      this.post_data.forEach((item, index) => {
        if (item.id == this.pitch_div_id) x = index;
        if (item.id == event.target.id) y = index;
      });
      this.post_data = this.moveArray(this.post_data, x, y);
      this.animation(x, y, this.pitch_div_id, event.target.id);
    },
    dragover(event) {
      //更改图标
      this.preventDefault(event);
    },
    dragleave(event) {},
    drop(event) {
      //关闭火狐默认打开事件
      this.preventDefault(event);
      this.stopPropagation(event);
    },
    animation(x, y, x_id, y_id) {
      let x_element = document.getElementById(x_id);
      let y_element = document.getElementById(y_id);
    },
    moveArray(array, x, y) {
      if (x < y) {
        array.splice(y + 1, 0, array[x]);
        array.splice(x, 1);
      } else {
        array.splice(y, 0, array[x]);
        array.splice(x + 1, 1);
      }
      return array;
    },

    addHandler(element) {
      let arr = [
        "dragstart",
        "drag",
        "dragend",
        "dragenter",
        "dragover",
        "dragleave",
        "drop"
      ];
      arr.forEach(item => {
        let getEvent = event => {
          let event_new = this.getEvent(event);
          this[item](event_new);
        };
        if (element.addEventListener) {
          element.addEventListener(item, getEvent, false);
        } else if (element.attachEvent) {
          element.attachEvent("on" + item, getEvent);
        } else {
          element["on" + item] = getEvent;
        }
      });
    },
    removeHandler(element, type, handler) {
      if (element.removeEventListener) {
        element.removeEventListener(type, handler, false);
      } else if (element.detachEvent) {
        element.detachEvent("on" + type, handler);
      } else {
        element["on" + type] = null;
      }
    },
    getEvent(event) {
      return event ? event : window.event;
    },
    getTarget(event) {
      return event.target || event.srcElement;
    },
    //取消事件默认动作
    preventDefault(event) {
      if (event.preventDefault) {
        event.preventDefault();
      } else {
        event.returnValue = false;
      }
    },
    stopPropagation(event) {
      if (event.stopPropagation) {
        event.stopPropagation();
      } else {
        event.cancelBubbles = true;
      }
    },
    //获取与目标节点事件相关的节点信息
    getRelatedTarget(event) {
      if (event.relatedTarger) {
        return event.relatedTarget;
      } else if (event.toElement) {
        return event.toElement;
      } else if (event.fromElement) {
        return event.fromElement;
      } else {
        return null;
      }
    }
  }
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style>
</style>

posted @ 2019-11-21 18:01  __松子  阅读(925)  评论(0编辑  收藏  举报