Vue.js + @shopify/draggable에서 SortTable
16217 단어 AdventCalendarVue.jsdrag&drop
소개
Vue.js와 @shopify/draggable을 사용하여 SortTable을 시도했습니다.
draggable.vue
<script>
import { Sortable } from '@shopify/draggable';
const removeElement = function(node) {
return node.parentElement.removeChild(node);
};
const insertElement = function(fatherNode, node, position) {
const refNode = (position === 0) ? fatherNode.children[position] : fatherNode.children[position - 1].nextSibling;
fatherNode.insertBefore(node, refNode);
};
export default {
props: {
value: {
required: true,
type: Array,
},
element: {
required: false,
type: String,
default: 'div',
},
draggableOptions: {
required: false,
type: Object,
default: () => ({}),
},
},
mounted() {
const draggable = new Sortable(this.$el, this.draggableOptions);
this.$once('hook:beforeDestroy', () => {
draggable.destroy();
});
draggable.on('sortable:start', e => {
this.$emit('start', e);
});
draggable.on('sortable:sort', e => {
this.$emit('sort', e);
});
draggable.on('sortable:sorted', e => {
this.$emit('sorted', e);
});
draggable.on('sortable:stop', e => {
if (e.oldIndex !== e.newIndex) {
const item = removeElement(e.dragEvent.source);
insertElement(e.dragEvent.sourceContainer, item, e.oldIndex);
this.spliceList([...this.value], e.oldIndex, e.newIndex);
}
this.$emit('stop', e);
});
},
methods: {
spliceList(list, oldIndex, newIndex) {
const item = list.splice(oldIndex, 1)[0];
list.splice(newIndex, 0, item);
this.$emit('input', list);
this.$emit('change', { item, oldIndex, newIndex });
},
},
render(h) {
return h(this.element, { attrs: this.$attrs }, this.$slots.default);
},
};
</script>
app.vue
<template>
<div id="app">
<Draggable
v-model="list"
element="ul">
<li
v-for="(row, index) in list"
:key="row.id || `key${index}`"
class="draggable-source">
{{ row.text }}
</li>
</Draggable>
</div>
</template>
<script>
import Draggable from './draggable.vue'
export default {
name: 'app',
data: () => ({
list: [
{ id: 1, text: 'テスト1' },
{ id: 2, text: 'テスト2' },
{ id: 3, text: 'テスト3' },
{ id: 4, text: 'テスト4' },
{ id: 5, text: 'テスト5' },
],
}),
components: {
Draggable,
},
}
</script>
sortable:stop
이벤트로 소트 된 DOM를 되돌리고, Vue data
자신을 정렬하고 있습니다.
결과
Reference
이 문제에 관하여(Vue.js + @shopify/draggable에서 SortTable), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/wakame_isono_/items/9b625a57e4321a7dc2d5
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
<script>
import { Sortable } from '@shopify/draggable';
const removeElement = function(node) {
return node.parentElement.removeChild(node);
};
const insertElement = function(fatherNode, node, position) {
const refNode = (position === 0) ? fatherNode.children[position] : fatherNode.children[position - 1].nextSibling;
fatherNode.insertBefore(node, refNode);
};
export default {
props: {
value: {
required: true,
type: Array,
},
element: {
required: false,
type: String,
default: 'div',
},
draggableOptions: {
required: false,
type: Object,
default: () => ({}),
},
},
mounted() {
const draggable = new Sortable(this.$el, this.draggableOptions);
this.$once('hook:beforeDestroy', () => {
draggable.destroy();
});
draggable.on('sortable:start', e => {
this.$emit('start', e);
});
draggable.on('sortable:sort', e => {
this.$emit('sort', e);
});
draggable.on('sortable:sorted', e => {
this.$emit('sorted', e);
});
draggable.on('sortable:stop', e => {
if (e.oldIndex !== e.newIndex) {
const item = removeElement(e.dragEvent.source);
insertElement(e.dragEvent.sourceContainer, item, e.oldIndex);
this.spliceList([...this.value], e.oldIndex, e.newIndex);
}
this.$emit('stop', e);
});
},
methods: {
spliceList(list, oldIndex, newIndex) {
const item = list.splice(oldIndex, 1)[0];
list.splice(newIndex, 0, item);
this.$emit('input', list);
this.$emit('change', { item, oldIndex, newIndex });
},
},
render(h) {
return h(this.element, { attrs: this.$attrs }, this.$slots.default);
},
};
</script>
app.vue
<template>
<div id="app">
<Draggable
v-model="list"
element="ul">
<li
v-for="(row, index) in list"
:key="row.id || `key${index}`"
class="draggable-source">
{{ row.text }}
</li>
</Draggable>
</div>
</template>
<script>
import Draggable from './draggable.vue'
export default {
name: 'app',
data: () => ({
list: [
{ id: 1, text: 'テスト1' },
{ id: 2, text: 'テスト2' },
{ id: 3, text: 'テスト3' },
{ id: 4, text: 'テスト4' },
{ id: 5, text: 'テスト5' },
],
}),
components: {
Draggable,
},
}
</script>
sortable:stop
이벤트로 소트 된 DOM를 되돌리고, Vue data
자신을 정렬하고 있습니다.
결과
Reference
이 문제에 관하여(Vue.js + @shopify/draggable에서 SortTable), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/wakame_isono_/items/9b625a57e4321a7dc2d5
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
<template>
<div id="app">
<Draggable
v-model="list"
element="ul">
<li
v-for="(row, index) in list"
:key="row.id || `key${index}`"
class="draggable-source">
{{ row.text }}
</li>
</Draggable>
</div>
</template>
<script>
import Draggable from './draggable.vue'
export default {
name: 'app',
data: () => ({
list: [
{ id: 1, text: 'テスト1' },
{ id: 2, text: 'テスト2' },
{ id: 3, text: 'テスト3' },
{ id: 4, text: 'テスト4' },
{ id: 5, text: 'テスト5' },
],
}),
components: {
Draggable,
},
}
</script>
Reference
이 문제에 관하여(Vue.js + @shopify/draggable에서 SortTable), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/wakame_isono_/items/9b625a57e4321a7dc2d5텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)