본문 바로가기

개발일지

[개발일지] Vue.js Trello 만들기 - 카드 이동, 이동 리팩토링, 카드 삭제

728x90
반응형

카드 이동

<카드 이동시키기>
드래그앤드랍 라이브러리 설치
$ npm i dragula
[board.vue]
import dragula from 'dragula'
import 'dragula/dist/dragula.css'
data() 상태값 추가
dragulaCards: null
updated() 추가 - 이동작업 일어났을 때 동작 추가
  updated() {
    // dragulaCards 초기화 작업
    if(this.dragulaCards) this.dragulaCards.destroy()
    
    // 유사배열을 NodeList->Array 하고 마우스를 놓았을 때 콘솔 출력
    this.dragulaCards = dragula([
      ...Array.from(this.$el.querySelectorAll('.card-list'))
    ]).on('drop', (el, wrapper, target, siblings) => {
      console.log('drop')
    })
  },
=> 카드를 드래그 하고 놓았을 때 drop 로그 출력

<카드 놓았을 때 포지션값 저장하기>
[cardItem] card.id, data.pos 바인딩
<div class="card-item" :data-card-id="data.id" :data-card-pos="data.pos">
이동 작업 id, pos 값 계산
    this.dragulaCards = dragula([
      ...Array.from(this.$el.querySelectorAll('.card-list'))
    ]).on('drop', (el, wrapper, target, siblings) => {
      const targetCard = {
        id: el.dataset.cardId * 1,
        pos: 65535
      }
      let prevCard = null
      let nextCard = null
      Array.from(wrapper.querySelectorAll('.card-item'))
        .forEach((el, idx, arr) => {
          const cardId = el.dataset.cardId * 1
          if(cardId == targetCard.id) {
            prevCard = idx > 0 ? {
              id: arr[idx -1].dataset.cardId * 1,
              pos: arr[idx -1].dataset.cardPos * 1
            } : null
            nextCard = idx < arr.length - 1 ? {
              id: arr[idx + 1].dataset.cardId * 1,
              pos: arr[idx + 1].dataset.cardPos * 1
            } : null
          }
        })

      if(!prevCard && nextCard) targetCard.pos = nextCard.pos / 2
      else if(!nextCard && prevCard) targetCard.pos = prevCard.pos * 2
      else if(prevCard && nextCard) targetCard.pos = (prevCard.pos + nextCard.pos) / 2

      console.log(targetCard)
      this.UPDATE_CARD(targetCard) // card update (id,pos)
    })
    ...mapActions([
      'FETCH_BOARD',
      'UPDATE_CARD' // 추가
    ]),

<카드를 추가할 때 포지션 값 지정하기>
[AddCard.vue]
// onSubmit()
const pos = this.newCardPos() // pos값 추가
this.ADD_CARD({title: inputTitle, listId, pos}) // pos 넘겨줌
// method 추가
    newCardPos() {
      const curList = this.$store.state.board.lists.filter(l => l.id === this.listId)[0]
      if (!curList) return 65535
      const {cards} = curList
      if (!cards.length) return 65535
      return cards[cards.length - 1].pos * 2 // card list 기존 값 있을 경우 마지막 pos의 2배로 지정
    },




카드 이동 리팩토링

dragula 모듈 분리
[utils/dragger.js] 생성,
init, sibling 메소드 생성, board에서 필요한 코드 이동

board 코드 정리 




카드 삭제


[CardItem.vue] 삭제버튼 추가
<a class="delete-card-btn" href="" @click.prevent="onDelete">&times;</a>

api - card destroy 추가
  destroy(id) {
    return request('delete', `/cards/${id}`)
  }

DELETE action 추가
  // card 삭제
  DELETE_CARD({dispatch, state}, {id}) {
    return api.card.destroy(id)
    .then(() => dispatch('FETCH_BOARD', {id: state.board.id}))
  }

[CardItem.vue] 삭제 메소드 구현

  methods: {
    ...mapActions([
      'DELETE_CARD'
    ]),
    onDelete() {
      if (!window.confirm('Delete this card?')) return
      this.DELETE_CARD({id: this.data.id})
    }
  } 


728x90
반응형