컴포넌트를 생성하고 등록까지 완료하였으니 이제 컴포넌트 역할에 맞춰 컴포넌트 기능을 구현해 보겠습니다. 컴포넌트별로 구현할 기능은 아래와 같습니다.
TodoHeader : 애플리케이션 이름 표시 TodoInput : 할 일 입력 및 추가 TodoList : 할 일 목록 표시 및 특정 할 일 삭제 TodoFooter : 할 일 모두 삭제 |
애플리케이션 제목을 보여주는 TodoHeader 컴포넌트
먼저 간단히 TodoHeader 컴포넌트를 꾸며보겠습니다.
애플리케이션 제목을 추가하겠습니다. 어떤 애플리케이션인지 파악하기 쉽게 애플리케이션 제목 정도만 추가하겠습니다. 이 앞에 TodoHeader 컴포넌트를 등록하면서 간단하게 <div> 태그 정도만 작성했는데, <div> 태그를 삭제하고 <header>와 <h1> 태그를 활용하여 아래처럼 제목을 표시합니다.

CSS로 제목 꾸미기
제목의 스타일링을 위해 최상위 컴포넌트인 App.vue와 TodoHeader.vue에 다음과 같이 CSS를 추가합니다.


App.vue와 TodoHeader.vue에 추가한 스타일의 역할은 각각 다음과 같습니다.
컴포넌트
|
CSS 속성
|
설명
|
App.vue
|
background-color
|
애플리케이션 전체의 배경 색을 꾸미기 위해 지정
|
text-align
|
애플리케이션 전체에서 사용하는 텍스의 정렬 방식을 선택
|
|
border-style
|
할 일을 입력하는 인풋 박스의 테두리 모양을 정의
|
|
box-shadow
|
할 일을 입력하는 인풋 박스와 할 일 아이템의 아래 그림자 정의
|
|
TodoHeader.vue
|
color
|
애플리케이션 제목의 텍스트 색깔을 지정
|
font-weight
|
애플리케이션 제목의 텍스트 굵기를 지정
|
|
margin
|
애플리케이션 제목의 텍스트 여백을 지정
|
그리고 <style> 태그에 사용된 scoped는 뷰에서 지원하는 속성이며, 스타일 정의를 해당 컴포넌트에만 적용하겠다는 의미입니다.

할 일을 입력하는 TodoInput 컴포넌트
이번에는 TodoInput 컴포넌트를 구현해 보겠습니다.
인풋 박스와 버튼 추가하기
먼저 텍스트 값을 입력받기 위한 <input> 태그와 텍스트 값을 저장하기 위한 <button> 태그를 추가합니다. <button> 태그의 이름은 '추가'로 지정합니다. 태그를 추가하면 화면에서 input 텍스트가 있던 자리에 인풋 박스와 버튼이 생깁니다. 인풋 박스에 텍스트를 입력했을 때 뷰 인스턴스에서 텍스트 값을 인식할 수 있게 v-model 디렉티브와 데이터 속성 newTodoInput을 다음과 같이 추가합니다.

위 코드를 저장하고 다시 애플리케이션을 실행한 후 뷰 개발자 도구를 엽니다. 뷰 개발자 도구에서 'Components' 탭의 <App> 아래 있는 <TodoInput> 부분을 클릭하면 newTodoInput의 값이 '' 로 되어있습니다. 이제 인풋 박스에 Hello라는 텍스트를 입력하면서 newTodoItem의 값을 지켜보면 텍스트를 입력함에 따라 newTodoInput의 값도 갱신되는 것을 볼 수 있습니다.

텍스트를 저장하기 위한 버튼 이벤트 추가하기
인풋 박스에 입력한 텍스트 값을 뷰에서 인식할 수 있게 되었습니다. 이제 입력한 텍스트 값을 데이터 저장소인 로컬 스토리지에 저장하기만 하면 됩니다. [추가] 버튼을 클릭했을 때 특정 동작을 수핼할 수 있게 v-on:click에 버튼 이벤트 addTodo를 지정하겠습니다. 그리고 버튼 이벤트 addTodo()의 로직은 methods에 정의합니다.

버튼이 정상적으로 동작하는지 확인하기 위해 인풋 박스에 입력된 텍스트 데이터를 console.log()로 출력해 보겠습니다. 인풋 박스에 텍스트을 입력하고 [추가] 버튼을 클릭하면 다음과 같이 콘솔에 텍스트 값이 표시 됩니다.

이와 같이 [추가] 버튼을 클릭했을 때 버튼 이벤트가 정상적으로 동작하는 것을 확인하였습니다.
입력받은 텍스트를 로컬 스토리지에 저장하기
버튼 이벤트가 제대로 동작하는 것을 확인했으니 확인용으로 작성한 console.log(this.newTodoItem);은 삭제합니다. 그리고 입력받은 텍스트를 로컬 스토리지의 setItem() API를 이용하여 저장합니다. setItem()는 로컬 스토리지에 데이터를 추가하는 API입니다. API 형식은 키, 값 형태이며 저장 기능을 최대한 단순하게 하기 위해 키, 값 모두 입력받은 텍스트로 지정합니다.

localStorage.setItem() 코드
methods의 내용을 위와 같이 변경하고 저장합니다. 그리고 나서 인풋 박스에 텍스트을 입력하고 [추가] 버튼을 클릭하면 로컬 스토리지에 텍스트 값이 저장됩니다. 로컬 스토리지에 저장된 것을 확인하려면 크롬 개발자 도구의 [애플리케이션 - 로컬 스토리지 - http://localhost:8087]를 클릭해 확인합니다. 텍스트 값이 올바르게 저장된 것을 확인할 수 있습니다.

이렇게 해서 TodoInput 컴포넌트의 입력된 할 일 저장 기능을 구현하였습니다.
addTodo() 안에 예외 처리 코드 넣기
인풋 박스에 입력된 텍스트가 없을 경우 로컬 스토리지에 데이터가 저장되지 않게 예외 처리 코드를 추가해 보겠습니다. 먼저 기존의 addTodo() 메서드를 아래와 같이 변경합니다.

변경 전의 addTodo()는 로컬 스토리지로 데이터를 저장하는 코드만 있었습니다. 그래서 만약 인풋 박스에 텍스트를 입력하지 않은 상태에서 [추가] 버튼을 클릭하면 빈 데이터가 로컬 스토리지에 저장되는 문제가 생깁니다. 여기서 this.clearInput()을 보면 아래의 clearInput() 메서드를 호출하고 있다는 것을 금방 눈치챌 수 있습니다. addTodo() 메서드 안에서 this를 사용하면 해당 컴포넌트를 가리킵니다. clearInput() 메서드는 App 컴포넌트에 정의되어 있으므로 addTodo() 에서 this를 사용하면 clearInput() 메서드에 접근할 수 있습니다. data 속성에 정의한 newTodoItem을 addTodo()에서 this.newTodoItem으로 접근한 것과 같은 원리입니다.
아이콘 이용해 직관적인 버튼 모양 만들기
인풋 박스와 버튼을 다루기 편하게 약간의 CSS 스타일링을 하겠습니다. 현재 버튼은 <button> 태그와 '추가'라는 텍스트를 사용하고 있습니다. 앞에서 설치한 어썸 아이콘의 +아이콘을 이요하면 더 직관적인 버튼 모양을 만들 수 있습니다.
<template> 태그에 기존 <button> 태그를 삭제하고 <span>, <i> 태그를 아래와 같이 추가합니다.

<template> 변경 내용은 다음과 같습니다.
- placeholder: 인풋 박스의 힌트 속성
- v-on:keyup.enter: 인풋 박스에서 Enter를 눌렀을 때 동작하는 속성
- <span>: <button> 대신 클릭 이벤트를 받을 태그
- <i calss="fa fa-plus">: 어썸 아이콘의 +아이콘을 추가
TodoInput 컴포넌트의 CSS코드를 다음처럼 수정합니다.

<style> 변경 내용은 다음과 같습니다.
CSS 속성
|
설명
|
outline
|
할 일을 입력하는 인풋 박스의 선 스타일 지정
|
background
|
인풋 박스의 배경색 지정
|
height
|
인풋 박스의 높이 설정
|
line-height
|
인풋 박스에 입력되는 텍스트의 중앙 정렬을 위해 설정
|
border-radius
|
인풋 박스의 동근 테두리 속성 설정
|
float
|
할 일 추가 버튼이 표시될 위치 정의
|
vertical-align
|
할 일 추가 아이콘의 수직 정렬 정의
|

지금까지 수정한 코드의 실행 결과는 위와 같습니다.
'Vue' 카테고리의 다른 글
모두 삭제하기 버튼 (0) | 2023.10.20 |
---|---|
할 일 목록 만들기 (0) | 2023.10.20 |
프로젝트 초기 설정 (0) | 2023.10.20 |
뷰 CLI 설치, 프로젝트 생성 (0) | 2023.10.20 |
뷰 템플릿, 데이터 바인딩 (0) | 2023.10.20 |