내가 한 노력들

[ Laravel + Vue.js ] 나만의 To Do List 만들기 - Detail 화면 본문

IT 공부/Laravel

[ Laravel + Vue.js ] 나만의 To Do List 만들기 - Detail 화면

JONGI-N CHOI 2021. 8. 30. 19:27

To Do 목록을 클릭했을 때, 해당 To Do의 Title과 상세내용 및 생성날짜, 마감일등을 확인할 수 있다.

 

그리고, 완료/복구 처리, 상세내용 수정이 가능하다.

 

ToDoView.vue

 

<div class="col-span-5 p-2" :style="hiddenText" @click="onClickToDetail(toDo)" :class="{ Done : !mode }">{{ toDo.title }}</div>

ToDo를 보여주던 ToDoView.vue의 div를보면 @Click 이벤트로 onClickToDetail()함수를 볼 수 있다.

이 함수가 목록을 클릭했을 때, Detail화면을 보여주도록 해주는 기반의 함수가 된다.

 

onClickToDetail(data) {
            this.$emit('onClickToDetail', data);
        },

onClickToDetail함수는 해당 To Do 데이터를 파라미터로 받아서 부모 컴포넌트로 onClickToDetail이라는 함수로 

$emit으로 보냅니다.

 

 

ToDoList.vue

onClickRedirect(data) {                       
            this.ToDo = data;
        },

부모 컴포넌트인 ToDoList.vue에서는 받아온 함수와 파라미터 data를 ToDo라는 이름의 변수에 넣습니다. 

 

<template v-if="ToDo === ''">
	<div class="w-4/5 flex flex-col px-16">
</template>

<template v-else>
	<ToDoDetail :to-do="ToDo" @show-set-detail="ShowSetDetail"/>
</template>

template에서는 v-if문을 이용, ToDo라는 값이 비어있으면, 기존의 메인화면을 보여주고, ToDoDetail 컴포넌트에 

방금 받아온 ToDo라는 변수 데이터를 보내주는 것을 볼 수 있습니다. 

 

ToDoDetail.vue

<script>
export default {
    props: ['toDo'],
    }
</script>

ToDoDetail.vue에서는 우선 부모 컴포넌트에서 받아온 ToDo를 props로 받아줍니다. 

<div class="col-start-1 col-end-6" :class="{ Done : !mode }" :style="hiddenText">{{ toDo.title }}</div>
            <div v-if="mode" class="col-start-7">
                <div class="grid grid-cols-2 text-sm">
                    <div>CreatedAt</div>
                    <div> {{ String(toDo.created_at).slice(0, 10) }}</div>
                </div>
                <div class="grid grid-cols-2 text-sm">
                    <div>DeadLine</div>
                    <div>{{ checkDeadLine(toDo.deadline) }}</div>
                </div>
            </div>

그럼 이제 받아온 toDo를 이용해서, Template에 표시해주면 됩니다. 

 

 


 

완료 / 복구

 

완료 버튼을 누르면 

기존의 배경화면이 변하고, 글씨부분에는 가운데에 줄이 생기게 됩니다.

 

그리고 생성날짜와 마감일부분엔 완료했다는 의미의 Done이라는 문구가 보여지게 됩니다.

 

그리고 완료였던 버튼은 복구라는 버튼으로 바뀌게 됩니다.

 

 

여기서 복구 버튼을 누르게 되면

다시 원래의 Detail화면으로 바뀌게 됩니다. 

 

위의 기능을 구현하기 위해서는 우선 스타일을 바꿔야하기 때문에 클래스 바인딩이라는 것을 사용합니다. 

 

 

클래스 바인딩

<div class="col-start-1 col-end-6" :class="{ Done : !mode }" :style="hiddenText">{{ toDo.title }}</div>

위의 div를 보면  ":class="{ Done : !mode }"" 부분을 볼 수 있는데, 이것은 

 

mode라는 변수 값(true/false)에 따라서 해당 태그에 class="Done"가 생기게할지 안되게 할지 정할 수 있습니다.

 

! mode 이기 때문에 mode 값이 false일 경우에는 해당 div는 Done라는 값의 class 값을 가지게 되는 것 입니다. 

 

또한, :style="hiddenText"를 볼 수 있는데, 기본 html 속성 앞에 ":"를 붙히면 거기에는 JS영역이 되어서 변수나 여러 연산을 수행할 수 있습니다. 

 

위의 코드는 data() 부분에 hiddenText라는 style속성을 저장해놓고 편하게 사용하는 것 입니다.

data() {
        return {
            mode: this.toDo.completion_is ? false : true,                      
            hiddenText: {
                overflow: 'hidden',
                textOverflow: 'ellipsis',
                whiteSpace: 'nowrap'
            },  
        }
    },

 

 

<div class="text-center">            
  <button  v-if="mode" type="button" class="btn btn-warning mr-2" @click="complete(toDo.id)">完了</button>       
  <button v-else type="button" class="btn btn-warning mr-2" @click="complete(toDo.id)">復旧</button>    
</div>

버튼은 v-if를 사용해서 mode라는 변수가 true일 때는 완료 버튼이 보이게, false일 때는 복구가 보이도록 한다.

 

그리고 해당 버튼을 클릭하면, @Click 이밴트를 이용해서, complete라는 함수를 실행시킨다.

 

 

complete(id) {
          axios.get('api/todo/complete', {
              params: {
                  ToDoId: id
              }
          });
        this.mode = !this.mode; 
      },

 complete함수는 axios.get을 이용해서 DB와 통신을 합니다. 

 

 

api.php

Route::get('/todo/complete', [ToDoListController::class, 'complete']);

 

ToDoListController.php

public function complete() {        
        $ToDoList = ToDoList::find(request('ToDoId'));
        $ToDoList->completion_is = !($ToDoList->completion_is);
        $ToDoList->save();
        return;
    }

버튼이 눌릴 때마다, completion_is라는 속성의 boolean값을 토글로 변경한다.