지난 포스팅에 이어서 Vue.js로 트렐로와 비슷한 앱을 만드는 작업을 블로그로 정리해 보려고 한다.
이번에 만들어볼 기능은
- 카드 이름을 실시간으로 수정하고
- 카드를 다른 리스트로 이동하는 기능이다.
1. 카드 이름 실시간으로 수정하기
예를 들어 첫번째 리스트인 A 리스트에서 첫번째 카드인 TaskA의 이름을 수정하고 싶을 때, 바로 이름을 수정하고 그 수정된 이름이 저장이 되게 하고 싶다. 이 때 사용하는 지시자는 v-model이다. v-model은 form의 input 요소와 컴포넌트의 output을 변화시키고 싶을 때 사용한다. 예를 들어 <input v-model="message"> 라고 하면 이 input에 입력하는 값이 컴포넌트의 message 데이터에 자동으로 저장되고 실시간으로 바뀔 때 마다 그 변화가 반영된다.
아래 소스코드 line 13에서 v-model에 왜 그냥 v-for의 card를 안 쓰고 list.cards[index]로 썼는지 궁금증이 들 수 있다. 여기서 이전 코드처럼 그냥 v-for="card in cards"에서 card를 v-model로 바인드를 해 주게 되면 이 card는 지역변수이기 때문에 컴포넌트의 데이터와 올바르게 바인딩이 되지 않는다. v-for가 돌면서 계속 새로운 card가 선언이 되기 때문이다.
뷰와 데이터가 상호간에 바인딩이 되어 양 쪽으로 흐르는 이러한 방식을 양 방향 바인딩이라고 한다. 데이터가 양 방향으로 바인딩이 되어 있어 어느 쪽(template 또는 script)을 수정해도 다른 한 쪽 까지 수정사항이 반영되는 개념이다. v-model에 대한 좀 더 자세한 개념은 아래 링크를 참고하도록 하자.
https://vuejs.org/v2/api/#v-model
이렇게 카드의 이름을 실시간으로 수정하게 만든 코드는 다음과 같다.
2. 카드를 다른 리스트로 이동시키기
카드가 들어있는 리스트를 이동 시킬 일이 충분히 생길 수 있다. 예를 들면 트렐로에서는 어떤 하나의 프로세스를 pending, to do, doing, done 등과 같이 진행 상황에 맞게 리스트를 구분해 놓기도 한다. 실제 트렐로는 드래그 앤 드랍으로 (훨씬 더 편리하게) 이동을 하지만, 일단 우리는 초보적인 방법으로 화살표를 클릭했을 때 좌우로 이동하도록 만들어 보려고 한다.
각각의 카드들에 대해서 좌우 화살표를 만들어 준다. 이 때 가장 왼쪽에 있는 리스트의 카드는 > 만 있어야 하고, 반대로 가장 오른쪽에 있는 리스트의 카드는 < 만 있어야 할 것이다.
나는 여기서 v-if를 사용했다. v-if는 조건적으로 요소를 렌더링 하는 지시자이다. 마찬가지로 v-else, v-else-if 등의 지시자도 있다. 만약에 해당 카드의 리스트 index가 0이면 가장 왼쪽에 있다는 뜻이고, index가 board.length-1이면 가장 오른쪽에 있다는 뜻이므로 그렇게 조건을 걸어주면 가장 왼쪽, 가장 오른쪽을 처리할 수 있다.
각각의 화살표를 누를 당시의 listIdx와 cardIdx 두 파라미터를 받아와서 moveLeft() 메서드와 moveRight() 메서드를 만들어 준다. 먼저 기존의 배열에서 해당 card를 삭제해 주는데, 여기서는 splice라는 자바스크립트 배열 메서드를 사용한다. 그리고 좌우 중 해당 카드가 이동할 리스트에 card를 push() 해주면 된다.
이렇게 간단하게 만들어 본 트렐로 클론 데모이다. 어려운 개념은 사실 없다. 하지만 프론트엔드 개발자로 취업하는 과정에서 과제를 수행하기 위해서는 이정도만 기본적으로 잘 쓸 수 있어도 왠만한 과제는 수행하는데 무리가 없을 것 같다. 모든 vue 개발자들의 건승을 빈다!
TrelloClone Demo
'Web Frontend Developer' 카테고리의 다른 글
<FE면접질문> #5. 자료구조 (1) | 2020.06.04 |
---|---|
<FE면접질문> #4. JavaScript (Part 2) (1) | 2020.06.02 |
Vue.js로 간단한 Trello 클론 만들어 보기 - Part1 (0) | 2020.05.25 |
<FE면접질문> #3. JavaScript (Part 1) (0) | 2020.05.22 |
[TroubleShooting] Content-type: x-www-form-urlencoded에서 POST 데이터 보내기 (0) | 2020.05.21 |