因业务场景需要一个可拖拽修改节点位置的树形组件,因此动手撸了一个,乘此机会摸了一把html5原生拖拽。近期有时间将核心部分代码抽出,简单说下实现方式。
1.树形结构-组件递归使用
树形结构非常简单,tree组件作为父组件,结构如下
tree.vue
复制代码
vue组件允许在它们自己的模板中调用自身,因此可以形成树形结构,在组件中必须填写唯一的name。
tree-node.vue
复制代码
2.HTML5拖拽api
1.draggable属性规定元素是否可拖动,目前Internet Explorer 9+, Firefox, Opera, Chrome, and Safari 支持 draggable 属性
2.HTML 5 拖放api
ondragstart: 元素开始被拖动时触发 作用在拖拽元素上
ondragenter:当拖曳元素进入目标元素的时候触发的事件,作用在目标元素上
ondragover:拖拽元素在目标元素上移动的时候触发的事件,作用在目标元素上
ondragleave:拖拽元素拖离开了目标元素时触发,作用在目标元素上
ondrop:被拖拽的元素在目标元素上同时鼠标放开触发的事件,作用在目标元素上
ondragend:当拖拽完成后触发的事件,作用在被拖曳元素上
3.拖拽节点
定义变量
处理拖拽节点需要几个关键变量
当前拖拽的节点
拖拽时经过的节点
最终放置的节点
因此定义了一个用于保存拖拽信息的对象
dragOverStatus: {
overNodeKey: "",
dropPosition: "",
dragNode: {}
}
复制代码
绑定拖拽事件
这里将ondragstart事件绑定在子元素上,将其他事件绑定在父元素上,因为在测试真机IE10的时候,发现ondragstart和其他事件绑定在同一个元素上,无法触发ondragenter等事件。
复制代码mounted() {
//绑定拖拽事件
if (this.root.draggable) {
this.$refs.draggAbleDom.draggable = !this.nodeData.noDrag;
this.$refs.draggAbleDom.ondragstart = this.onDragStart;
this.$refs.dropTarget.ondragenter = this.onDragEnter;
this.$refs.dropTarget.ondragover = this.onDragOver;
this.$refs.dropTarget.ondragleave = this.onDragLeave;
this.$refs.dropTarget.ondrop = this.onDrop;
this.$