-
Vue 입문 - todolist 만들어보기 1 - 시작하기Study/개발 2021. 6. 7. 00:32
들어가며
이번에 회사에서 맡은 프로젝트가 Vue를 사용하기 때문에 Vue를 시작하게 되었다.
Vue는 js 프레임워크 중 하나로, 쉽게 FE 개발을 할 수 있다. 리액트를 해봤다면 더 쉬울 것이다. Vue 학습을 위해 todolist를 만들며 연습해본 과정을 정리해봤다.Vue 시작하기
Hello World!
가장 간단한 형태의 Vue app은 다음과 같이 만들 수 있다.
<script>
태그로 cdn을 사용해서 Vue를 사용할 수 있다.Vue
라는 생성자 함수가 전역에 등록되어 이를 사용할 수 있게 된다.지정해준 옵션(data와 메서드 등)은
_init
을 통해 Vue 인스턴스(this
)에 등록한다. 그러므로, 인스턴스가 생성된 후인 created 이후단계부터 프로퍼티에 접근할 수 있다.<!-- index.html --> <html> <head> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> </head> <body> <div id="app"> <span> {{ message }} </span> </div> <script src="index.js"></script> </body> </html>
// index.js var app = new Vue({ el: '#app', data: { message: 'Hello World!' } })
index.js를 보면
app
이라는 새로운 Vue인스턴스를 생성한다. Vue 생성자함수는 옵션 객체를 인자로 호출되고 있다. 옵션 객체의 내부에는el
과data
가 있다.el
은 css selector를 값으로 가진다. 해당 값을document.querySelector
처럼 검색하여 Vue를 마운트할 element를 찾는다. 위 예시에서는<div id='app'>
부분이 여기에 해당한다. 이 element에는 이제 Vue 템플릿 문법이 적용되어, mustache 구문{{ ... }}
으로 Vue 인스턴스에 등록된 식별자를 사용할 수 있다.위 html을 띄우면 다음과 같은 화면을 볼 수 있다. {{ message }} 였던
<span>
태그의 내부 textContent가 자동으로 Vue인스턴스의 data 속성으로 등록된message
값으로 바뀐 것을 알 수 있다.이런 방식으로 작동하기 때문에
<span>
부분을<div id='app'>
밖으로 빼면{{ message }}
가 치환되지 않고 그대로 표시되는 것을 볼 수 있다.나중에 알아보겠지만, data 외에도 method 등을 등록해 사용할 수 있다. Vue를 써봤던 사람이라면 흔히 쓰던 컴포넌트 방식이랑 좀 달라서 어색할 수 있지만, 가장 기본적인 Vue 앱은 이렇게 동작한다.
기본적인 todolist 만들기
위 방식으로 간단한 todolist를 작성해 보기로했다. 복잡한 기능은 제외하고 기본 기능만 구현한다. 우선, 할일들을 아래와 같이 목록으로 나타낼 수 있어야 한다.
- 할일 1
- 할일 2
- 할일 3
Vue 적용해보기
우선 마크업을 작성해본다. 위 html에서 app 내부에 리스트를 만들어준다. 우선 할일은 하나만 작성해본다.
... <div id="app"> <ul> <li>할일 1</li> </ul> </div> ...
"할일 1"으로 하드코딩되어있는 부분이 원래의 투두리스트라면 우리가 원하는 데이터가 들어가는 부분이다. 즉, 변경될 수 있는 부분이다. 위에서 이런 부분을 Vue의 data를 이용해서 표현하는 것을 보았다. 그 방식을 다시 적용해본다.
... <div id="app"> <ul> <li>{{ todo }}</li> </ul> </div> ...
// index.js var app = new Vue({ el: '#app', data: { todo: '할일 1' } })
메서드 추가하기
데이터는 추가해봤지만, 아직 데이터를 변경해보지는 못했다. Vue를 생성할 때 만든 데이터가 그대로 유지된다. 이번에는 클릭 시 완료처리를 할 수 있도록 메서드를 추가해보자.
완료처리된 항목은 취소선을 표시한다. 그러려면 class에 inactive를 줘서 css로 처리해줄 수 있다. 즉, 클릭하면 inactive라는 클래스가 토글되도록 만들어보자.
<li class="inactive">할일 1</li>
위와 같이 만들어져야하는데, 이제 "할일 1" 뿐만 아니라 class="inactive"도 우리가 Vue를 통해 제어해야하는 부분이 되었다. 그럼 클래스 명을 todo-class라는 식별자로 만들어보자.
class는 속성이므로, Vue에서 컨트롤 하려면
v-bind
라는 기능을 통해 Vue의 식별자들과 binding해주어야한다. 다음과 같이 나타낼 수 있다.... <div id="app"> <ul> <li v-bind:class="todoClass">{{ todo }}</li> </ul> </div> ...
// index.js var app = new Vue({ el: '#app', data: { todo: '할일 1', todoClass: 'inactive', } })
크롬 개발자 도구를 보면v-bind
를 사용해서 클래스에 inactive가 추가된 것을 알 수 있다. 하지만 할일의 초기 값이 비활성인 것은 적절하지 않다. 초기값은 활성 상태고, 클릭할 때 비활성/활성이 토글되어야한다. 이게 가능하도록 메서드를 만들어서 데이터를 조작해보자.// index.js var app = new Vue({ el: '#app', data: { todo: '할일 1', todoClass: null, }, methods: { onClickTodo() { this.todoClass = this.todoClass ? null : 'inactive'; } } })
메서드는 옵션 객체의
methods
에 추가된다. 이렇게 만든 메서드를 템플릿에 등록하려면v-on
을 사용해야한다. 기존 html의 onClick 등 이벤트 핸들러와 유사한 방식으로 사용한다. 다음 예시와 같다.<li v-bind:class="todoClass" v-on:click="onClickTodo">{{ todo }}</li>
click
자리에 다른 이벤트를 원한다면 다른 이벤트를 사용하면 된다. 이제 클릭하면 class가 inactive가 되고, 다시 클릭하면 클래스가 없어지는 것을 볼 수 있다.스타일 변화를 위해 css만 추가해주면 제대로 작동한다.
/* style.css */ .inactive { text-decoration: line-through; }
<html> <head> <link rel="stylesheet" href="style.css"/> ...
투두 아이템 추가
지금까지 아이템 하나를 만들었다. 그럼 여러개를 추가해볼 수 있다. 근데 만약 똑같은 메서드와 데이터를 이용한 상태로 템플릿만 복사-붙여넣기 한다면 다음과 같이 모든 데이터가 똑같아 진다.
각각 데이터를 data1, data2, data3, ... 으로 만들고 그 마다의 메서드를 메서드1, 메서드2, 메서드3, ... 으로 일단 만들 수는 있지만, 그렇게 되면 데이터는 계속 세개만 다룰 수 있고 추가하거나 줄일 수가 없어서 좋은 방식이 아니다.
// 안좋은 예 data: () => ({ todo1: '할일 1', todoClass1: null, todo2: '할일 1', todoClass2: null, }), methods: { onClickTodo1() { this.todoClass = this.todoClass ? null : 'inactive'; } onClickTodo2() { this.todoClass = this.todoClass ? null : 'inactive'; } }
더 좋은 방식은 코드의 재사용이다. todoitem을 분리해서 재사용할 수 있는 코드로 만들고, data와 method는 각각이 들고 있도록 todolist와 todoitem을 분리 하는 것이다. 다음 예시를 보는 것이 더 쉽다.
Vue.component('todo-item', { template: ` <li v-bind:class="todoClass" v-on:click="onClickTodo">{{ todo }}</li> `, data: () => ({ todo: '할일 1', todoClass: null, }), methods: { onClickTodo() { this.todoClass = this.todoClass ? null : 'inactive'; } } }) var app = new Vue({ el: '#app', })
<div id="app"> <ul> <todo-item></todo-item> <todo-item></todo-item> <todo-item></todo-item> </ul> </div>
Vue.component
를 사용해서 기존에 Vue 생성자의 옵션 객체로 있던 data와 methods를 분리해냈다. Vue.component는 전역 뷰 컴포넌트를 생성하는 함수로, 이처럼 코드를 분리할 수 있게 해준다. 첫번째 인자에는 html에서 사용할 이름이 들어가고, 두번째 인자에는 옵션이 들어간다.옵션의 template은 해당 컴포넌트를 html에 사용했을 때 어떤 엘리먼트로 대체할것인지를 나타내고, data와 method는 Vue 생성자를 쓸 때와 같지만, 인스턴스별로 독립된 스코프를 갖게 된다.
Props 사용하기
지금은 세 todo-item 모두 "할일 1" 이라는 내용이 표시된다. 이 부분을 개선해보자.
todo-item
에 데이터를 전달하여 표시될 텍스트로 설정되도록 하고싶다.<div id="app">
위에서 "app"을 div의 id에 전달하듯이
todo-item
도 attribute를 전달하는 방식으로 사용할 수 있다. props를 사용하면된다.Vue.component('todo-item', { props: ['todo'], template: ` <li v-bind:class="todoClass" v-on:click="onClickTodo">{{ todo }}</li> `, data: () => ({ todoClass: null, }), methods: { onClickTodo() { this.todoClass = this.todoClass ? null : 'inactive'; } } }) const todos = ['할일 1', '할일 2', '할일 3']; const app = new Vue({ el: '#app', })
<div id="app"> <ul> <todo-item v-bind:todo="'할일 1'"></todo-item> <todo-item v-bind:todo="'할일 2'"></todo-item> <todo-item v-bind:todo="'할일 3'"></todo-item> </ul> </div>
위 예시는
todo-item
컴포넌트의 props로todo
라는 인자를 받을 수 있다. 이 때 주의할점은v-bind:todo
에 값을 넘길 때 따옴표 안의 값이 js구문으로 해석되므로 문자열을 넣으려면"'할일 1'"
과 같이 작성해줘야한다.'할일 1'
로 작성하면todo
라는prop
에할일1
이라는 변수의 값을 할당하겠다는 뜻이 된다.반복문 사용하기
컴포넌트 형태로 만들었지만, 중복을 다 없애진 못했다. 바뀌는 부분은
todo
에 들어가는 값 뿐이기 때문에 반복문으로 처리하면 쉬울 듯 보인다.vue에서 반복문은
v-for
를 사용한다.<ul> <todo-item v-for="todo in todos" v-bind:todo="todo"> </todo-item> </ul>
위와 같이 사용하는데, v-for의 값으로 "todo in todos"라고 적어준 것을 볼 수 있다.
todos
라는 배열에 있는 원소 하나하나를 순회하는데, 그 원소를 참조할 때todo
라는 이름을 사용하겠다는 뜻이다. 그럼todos
가 정의되어 있어야한다.app
에 데이터로 이를 정의해준다.const app = new Vue({ el: '#app', data: () => ({ todos: ['할일 1', '할일 2', '할일 3'] }) })
처음에 비해 코드가 훨씬 간결해진 것을 볼 수 있다.
Vue의 가장 기본기능에 대해 만들어봤다. 사실 실제로는 이런식으로 잘 쓰지 않는다.
다음에는 todolist를 더 발전시켜 보겠다. script태그가 아닌 npm을 통해 vue를 설치하고, webpack을 사용해 모듈 방식으로 발전시켜볼 예정이다.출처
728x90'Study > 개발' 카테고리의 다른 글
Vue 입문 - todolist 만들어보기 5 - 편집 / 삭제 (0) 2021.10.10 Vue 입문 - todolist 만들어보기 4 - TodoItem (0) 2021.09.12 Vue 입문 - todolist 만들어보기 3 - 컴포넌트 (0) 2021.09.05 Vue 입문 - todolist 만들어보기 2 - npm/ webpack (0) 2021.07.11 자바스크립트 객체 지향 프로그래밍 (0) 2021.04.14