Skip to content

Commit ffab62b

Browse files
WIP
1 parent e02f0f5 commit ffab62b

File tree

7 files changed

+78
-65
lines changed

7 files changed

+78
-65
lines changed

example/components/simple.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
@start="dragging = true"
3737
@end="dragging = false"
3838
>
39-
<template v-slot:item="{ element }">
39+
<template #item="{ element }">
4040
<div class="list-group-item" :class="{ 'not-draggable': !enabled }">
4141
{{ element.name }}
4242
</div>

example/components/third-party.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
:component-data="collapseComponentData"
1717
item-key="id"
1818
>
19-
<template v-slot:item="{ element }">
19+
<template #item="{ element }">
2020
<el-collapse-item :title="element.title" :name="element.id">
2121
<div v-for="(lign, idx) in element.text" :key="idx">{{ lign }}</div>
2222
</el-collapse-item>

example/components/transition-example-2.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
@end="drag = false"
2323
item-key="order"
2424
>
25-
<template v-slot:item="{ element }">
25+
<template #item="{ element }">
2626
<li class="list-group-item">
2727
<i
2828
:class="

example/components/transition-example.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
@start="isDragging = true"
2323
@end="isDragging = false"
2424
>
25-
<template v-slot:item="{ element }">
25+
<template #item="{ element }">
2626
<li class="list-group-item">
2727
<i
2828
:class="

src/core/componentStructure.js

Lines changed: 39 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
1-
import { nextTick } from "vue";
2-
31
const getHtmlElementFromNode = ({ el }) => el;
2+
const addContext = (domElement, context) => (domElement.__draggable_context = context);
3+
const getContext = domElement => domElement.__draggable_context;
44

55
class ComponentStructure {
6-
constructor({ nodes: { header, default: defaultNodes, footer }, root, $el }) {
6+
constructor({
7+
nodes: { header, default: defaultNodes, footer },
8+
root,
9+
realList
10+
}) {
711
this.nodes = { header, default: defaultNodes, footer };
812
this.children = [...header, ...defaultNodes, ...footer];
9-
this.offsets = {
10-
header: header.length,
11-
footer: footer.length
12-
};
1313
this.externalComponent = root.externalComponent;
1414
this.rootTransition = root.transition;
1515
this.tag = root.tag;
16-
this.setHtmlRoot($el);
16+
this.realList = realList;
1717
}
1818

1919
get _domChildrenFromNodes() {
@@ -30,43 +30,44 @@ class ComponentStructure {
3030
return h(tag, attributes, option);
3131
}
3232

33-
setHtmlRoot($el) {
34-
if (!$el) {
35-
return;
36-
}
37-
this.$el = $el;
38-
nextTick(() => {
39-
this.visibleIndexes = this._computeIndexes();
33+
updated() {
34+
const {
35+
nodes: { default: defaultNodes },
36+
realList
37+
} = this;
38+
defaultNodes.forEach((node, index) => {
39+
addContext(getHtmlElementFromNode(node), {
40+
element: realList[index],
41+
index
42+
});
4043
});
41-
return this;
4244
}
4345

44-
_computeIndexes() {
46+
getUnderlyingVm(domElement) {
47+
return getContext(domElement);
48+
}
49+
50+
getVmIndexFromDomIndex(domIndex, $el) {
51+
const domChildren = $el.children;
52+
const domElement = domChildren.item(domIndex);
53+
const context = getContext(domElement);
54+
if (context) {
55+
return context.index;
56+
}
4557
const {
46-
_domChildrenFromNodes,
47-
offsets: { footer: footerOffset }
58+
nodes: { default: defaultNodes }
4859
} = this;
60+
const { length } = defaultNodes;
4961

50-
const domChildren = this.$el.children;
51-
const footerIndex = domChildren.length - footerOffset;
52-
const rawIndexes = [...domChildren].map((elt, idx) =>
53-
idx >= footerIndex
54-
? _domChildrenFromNodes.length
55-
: _domChildrenFromNodes.indexOf(elt)
56-
);
57-
return rawIndexes;
58-
}
59-
60-
computeVmIndex(domElement) {
61-
return this._domChildrenFromNodes.indexOf(domElement);
62-
}
62+
if (length === 0) {
63+
return -1;
64+
}
6365

64-
getVmIndexFromDomIndex(domIndex) {
65-
const { visibleIndexes } = this;
66-
const numberIndexes = visibleIndexes.length;
67-
return domIndex > numberIndexes - 1
68-
? numberIndexes
69-
: visibleIndexes[domIndex];
66+
const firstDomListElement = getHtmlElementFromNode(defaultNodes[0]);
67+
const indexFirstDomListElement = [...domChildren].findIndex(
68+
element => element === firstDomListElement
69+
);
70+
return domIndex < indexFirstDomListElement ? -1 : length;
7071
}
7172
}
7273

src/core/renderHelper.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,10 @@ function getRootInformation(tag) {
4545
};
4646
}
4747

48-
function computeComponentStructure({ $slots, tag, $el, realList, itemKey }) {
48+
function computeComponentStructure({ $slots, tag, realList, itemKey }) {
4949
const nodes = computeNodes({ $slots, realList, itemKey });
5050
const root = getRootInformation(tag);
51-
return new ComponentStructure({ nodes, root, $el });
51+
return new ComponentStructure({ nodes, root, realList });
5252
}
5353

5454
export { computeComponentStructure };

src/vuedraggable.js

Lines changed: 33 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -74,18 +74,29 @@ const draggableComponent = defineComponent({
7474

7575
props,
7676

77+
data() {
78+
return {
79+
error: false
80+
};
81+
},
82+
7783
render() {
78-
const { $slots, $attrs, tag, componentData, $el, realList, itemKey } = this;
79-
const componentStructure = computeComponentStructure({
80-
$slots,
81-
tag,
82-
$el,
83-
realList,
84-
itemKey
85-
});
86-
this.componentStructure = componentStructure;
87-
const attributes = getComponentAttributes({ $attrs, componentData });
88-
return componentStructure.render(h, attributes);
84+
try {
85+
this.error = false;
86+
const { $slots, $attrs, tag, componentData, realList, itemKey } = this;
87+
const componentStructure = computeComponentStructure({
88+
$slots,
89+
tag,
90+
realList,
91+
itemKey
92+
});
93+
this.componentStructure = componentStructure;
94+
const attributes = getComponentAttributes({ $attrs, componentData });
95+
return componentStructure.render(h, attributes);
96+
} catch (err) {
97+
this.error = true;
98+
return h("pre", { style: { color: "red" } }, err.stack);
99+
}
89100
},
90101

91102
created() {
@@ -97,8 +108,12 @@ const draggableComponent = defineComponent({
97108
},
98109

99110
mounted() {
111+
if (this.error) {
112+
return;
113+
}
114+
100115
const { $attrs, $el, componentStructure } = this;
101-
componentStructure.setHtmlRoot($el);
116+
componentStructure.updated();
102117

103118
const sortableOptions = createSortableOption({
104119
$attrs,
@@ -112,6 +127,10 @@ const draggableComponent = defineComponent({
112127
$el.__draggable_component__ = this;
113128
},
114129

130+
updated() {
131+
this.componentStructure.updated();
132+
},
133+
115134
beforeUnmount() {
116135
if (this._sortable !== undefined) this._sortable.destroy();
117136
},
@@ -137,14 +156,7 @@ const draggableComponent = defineComponent({
137156

138157
methods: {
139158
getUnderlyingVm(domElement) {
140-
const index = this.componentStructure.computeVmIndex(domElement);
141-
if (index === -1) {
142-
//Edge case during move callback: related element might be
143-
//an element different from collection
144-
return null;
145-
}
146-
const element = this.realList[index];
147-
return { index, element };
159+
return this.componentStructure.getUnderlyingVm(domElement) || null;
148160
},
149161

150162
getUnderlyingPotencialDraggableComponent(htmElement) {
@@ -192,7 +204,7 @@ const draggableComponent = defineComponent({
192204
},
193205

194206
getVmIndexFromDomIndex(domIndex) {
195-
return this.componentStructure.getVmIndexFromDomIndex(domIndex);
207+
return this.componentStructure.getVmIndexFromDomIndex(domIndex, this.$el);
196208
},
197209

198210
onDragStart(evt) {

0 commit comments

Comments
 (0)