Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- react
- 타입좁히기
- 커스텀
- 리액트
- 폰트적용하기
- typescript
- 타입스크립트
- 티스토리꾸미기
- 레이아웃쪼개기
- 2022
- Chart.js
- 성능최적화
- javascript
- click and drag
- JS console
- utilty type
- 제네릭
- React.js
- 공통컴포넌트
- NonNullable
- React Native
- CSS
- TSDoc
- vue.js
- reactjs
- returnType
- const 단언문
- 누구나 자료구조와 알고리즘
- 개발콘텐츠
- 반복줄이기
Archives
- Today
- Total
몽땅뚝딱 개발자
[Vue.js] Drag & Drop / 드래그 앤 드롭 본문
trello를 쓰면서 항상 궁금했던 Drag & Drop...
vue-draggable도 있지만 직접 만들어보려고 츄라이해보았다. (🤗)
요소를 클릭한 상태에서 요소를 올렸을 때, 요소 간 간격이 벌어지거나 부드럽게 떨어지는 CSS는 추후에 추가해보려한다.
📄 HTML
v-for로 요소를 감싸는 <div>와 드래그가 가능한 요소를 뿌린다.
드래그가 가능한 요소들을 감싸는 곳(여기서는 class명이 'col'인 <div>)에는 @drop 이벤트를 추가한다. 이 때, @dragenter와 @dragover에는 기본 동작을 막는 .prevent를 적용해주어야 @drop이 실행된다.
드래그가 가능해야하는 요소에는 draggable="true"를 추가해준다.
<div>
<div v-for="(item, idx) in lists" :key="item.id">
<div class="col"
@drop.prevent="onDrop($event, idx)"
@dragenter.prevent
@dragover.prevent
>
<div v-for="(numItem, idx) in item.numberList" :key="idx"
class="box"
@dragstart="startDrag($event, numItem, item.id)"
draggable="true"
>
<p>{{ numItem.content }}</p>
</div>
</div>
</div>
</div>
📄 JS
<script>
export default {
name: "MoveTest",
data() {
return {
lists: [
{
id: 1,
numberList: [ { content: 1 }, { content: 2 } ]
},
{
id: 2,
numberList: [ {content: 3}, {content: 4}, {content: 5}, {content: 6} ]
},
{
id: 3,
numberList: [ {content: 7}, {content: 8}, {content: 9} ]
}
]
};
},
methods: {
startDrag(event, item) {
event.dataTransfer.dropEffect = "move"
event.dataTransfer.effectAllowed = "move"
event.dataTransfer.setData("selectedItem", item.content)
},
onDrop(event, colNum) {
const selectedItem = Number(event.dataTransfer.getData("selectedItem"))
// 리스트에서 선택된 아이템과 같은 content 값을 가진 요소를 찾아 index를 반환한다.
let targetIdx
let targetItem
this.lists.forEach((obj, index) => {
obj.numberList.forEach((ob) => {
if(ob.content === selectedItem) {
targetIdx = index
targetItem = ob
}
})
})
// drop이 된 <div> index(=colNum)를 받아 리스트에 추가한다.
// 기존 리스트에서는 요소를 삭제한다. (splice() 사용)
this.lists[colNum].numberList.push(targetItem)
this.lists[targetIdx].numberList.splice(this.lists[targetIdx].numberList.indexOf(targetItem), 1)
},
},
};
</script>
📄 CSS
<style lang="scss">
.playground {
display: flex;
.col {
display: flex;
height: 500px;
width: 150px;
background-color: #fff;
border: 1px solid lightgrey;
margin-left: 5px;
flex-direction: column;
align-items: center;
border-radius: 8px;
.box {
width: 130px;
height: 50px;
background-color: #7b71b7;
margin-top: 10px;
border-radius: 5px;
p {
text-align: center;
line-height: 50px;
color: white;
}
}
}
}
</style>
개인적으로 공부한 내용을 정리하는 블로그로
잘못된 개념을 게시하지않도록 주의하고 있으나 오류가 있을 수 있습니다.
'Development > Vue.js' 카테고리의 다른 글
[Vue.js] push, replace, go (0) | 2022.02.14 |
---|---|
[Vue.js] 버튼으로 복사 및 붙여넣기 (0) | 2022.02.05 |
[Vue.js] 컴포지션(Composition) - provide와 inject (0) | 2022.01.17 |
[Vue.js] 컴포지션(Composition) - mixins (0) | 2022.01.17 |
[Vue.js] v-model (0) | 2022.01.12 |
Comments