|
@@ -34,8 +34,27 @@
|
|
>目的字段</el-checkbox
|
|
>目的字段</el-checkbox
|
|
>
|
|
>
|
|
</div>
|
|
</div>
|
|
- <div class="field-body">
|
|
|
|
- <div v-for="item in targetList" :key="item.code" class="field-item">
|
|
|
|
|
|
+ <div
|
|
|
|
+ class="field-body"
|
|
|
|
+ @drop.prevent="dropInnerElement"
|
|
|
|
+ @dragover.prevent="dragOver($event)"
|
|
|
|
+ @dragleave.prevent
|
|
|
|
+ >
|
|
|
|
+ <div
|
|
|
|
+ v-for="item in targetList"
|
|
|
|
+ :key="item.code"
|
|
|
|
+ :class="[
|
|
|
|
+ 'field-item',
|
|
|
|
+ {
|
|
|
|
+ 'after-drop': item.code === curDropElementCode && isDragDown,
|
|
|
|
+ 'before-drop': item.code === curDropElementCode && !isDragDown
|
|
|
|
+ }
|
|
|
|
+ ]"
|
|
|
|
+ :id="`field-item-${item.code}`"
|
|
|
|
+ draggable="true"
|
|
|
|
+ @dragstart="$event => dragStart($event, item)"
|
|
|
|
+ @dragend.prevent="dragEnd"
|
|
|
|
+ >
|
|
<el-checkbox v-model="item.checked" @change="targetItemChange">{{
|
|
<el-checkbox v-model="item.checked" @change="targetItemChange">{{
|
|
item.name
|
|
item.name
|
|
}}</el-checkbox>
|
|
}}</el-checkbox>
|
|
@@ -69,7 +88,12 @@ export default {
|
|
sourceAll: false,
|
|
sourceAll: false,
|
|
sourceList: [],
|
|
sourceList: [],
|
|
targetAll: false,
|
|
targetAll: false,
|
|
- targetList: []
|
|
|
|
|
|
+ targetList: [],
|
|
|
|
+ // drag
|
|
|
|
+ curDragElement: null,
|
|
|
|
+ curDropElementCode: null,
|
|
|
|
+ dragStartPageY: null,
|
|
|
|
+ isDragDown: false
|
|
};
|
|
};
|
|
},
|
|
},
|
|
watch: {
|
|
watch: {
|
|
@@ -157,6 +181,82 @@ export default {
|
|
});
|
|
});
|
|
this.$emit("input", targetFields);
|
|
this.$emit("input", targetFields);
|
|
this.$emit("change", targetFields);
|
|
this.$emit("change", targetFields);
|
|
|
|
+ },
|
|
|
|
+ // drag
|
|
|
|
+ getRelateElement(dom) {
|
|
|
|
+ let element = null;
|
|
|
|
+ let parentNode = dom;
|
|
|
|
+ while (!element && !parentNode.className.includes("field-body")) {
|
|
|
|
+ if (
|
|
|
|
+ !element &&
|
|
|
|
+ parentNode["id"] &&
|
|
|
|
+ parentNode["id"].includes("field-item")
|
|
|
|
+ ) {
|
|
|
|
+ element = parentNode;
|
|
|
|
+ } else {
|
|
|
|
+ parentNode = parentNode.parentNode;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return element;
|
|
|
|
+ },
|
|
|
|
+ getElementCode(fieldId) {
|
|
|
|
+ return fieldId.replace("field-item-", "");
|
|
|
|
+ },
|
|
|
|
+ getSiblingElement(fieldCode, offset) {
|
|
|
|
+ const pos = this.targetList.findIndex(elem => elem.code === fieldCode);
|
|
|
|
+ return this.targetList[pos + offset] || null;
|
|
|
|
+ },
|
|
|
|
+ moveElementToElement(curElement, toElementCode, isDragDown) {
|
|
|
|
+ const curPos = this.targetList.findIndex(
|
|
|
|
+ elem => elem.code === curElement.code
|
|
|
|
+ );
|
|
|
|
+ this.targetList.splice(curPos, 1);
|
|
|
|
+
|
|
|
|
+ const toPos = this.targetList.findIndex(
|
|
|
|
+ elem => elem.code === toElementCode
|
|
|
|
+ );
|
|
|
|
+ const offset = isDragDown ? 1 : 0;
|
|
|
|
+ this.targetList.splice(toPos + offset, 0, { ...curElement });
|
|
|
|
+ this.emitChange();
|
|
|
|
+ },
|
|
|
|
+ dragStart(e, element) {
|
|
|
|
+ this.dragStartPageY = e.pageY;
|
|
|
|
+ this.curDragElement = element;
|
|
|
|
+ },
|
|
|
|
+ dragOver(e) {
|
|
|
|
+ // console.log(e);
|
|
|
|
+ this.isDragDown = e.pageY > this.dragStartPageY;
|
|
|
|
+ if (e.target.className.includes("field-body")) {
|
|
|
|
+ const curDropElement = this.isDragDown
|
|
|
|
+ ? this.targetList.slice(-1)[0]
|
|
|
|
+ : this.targetList[0];
|
|
|
|
+ this.curDropElementCode = curDropElement.code;
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ const elementDom = this.getRelateElement(e.target);
|
|
|
|
+ if (!elementDom) return;
|
|
|
|
+
|
|
|
|
+ const fieldCode = this.getElementCode(elementDom.id);
|
|
|
|
+ const curDropElement = this.getSiblingElement(fieldCode, 0);
|
|
|
|
+ this.curDropElementCode = curDropElement.code;
|
|
|
|
+ },
|
|
|
|
+ dropInnerElement() {
|
|
|
|
+ if (this.curDragElement.code === this.curDropElementCode) return;
|
|
|
|
+
|
|
|
|
+ // 往下:target上一个位置
|
|
|
|
+ // 往上:target下一个位置
|
|
|
|
+ this.moveElementToElement(
|
|
|
|
+ this.curDragElement,
|
|
|
|
+ this.curDropElementCode,
|
|
|
|
+ this.isDragDown
|
|
|
|
+ );
|
|
|
|
+ },
|
|
|
|
+ dragEnd() {
|
|
|
|
+ this.curDragElement = null;
|
|
|
|
+ this.curDropElementCode = null;
|
|
|
|
+ this.dragStartPageY = null;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
};
|