Vue를 이용해서 TodoList를 만들어보자
0. 사전준비
작성하기 편하게 html과 js을 분리해준다.
html에는 기본적인 형식과 vue의 cnd을 넣어주고,
js에는 기본적인 틀을 만들어준다.
<div id="app">
<!-- 여기에 코드 작성 -->
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script src="./js파일.js"></script>
const { createApp,ref } = Vue
const app = createApp({
setup() {
return {
}
}
})
app.mount('#app')
1. Todo 항목 추가하기
해야하는 일을 담을 todos라는 배열과
새롭게 추가할 newTodo라는 항목을 만들어준다.
그리고 newTodo를 todos에 추가해줄 addTodo 함수도 정의해준다. (return에 추가하는건 생략)
const todos = ref([])
const newTodo = ref('')
const addTodo = function () {
todos.value.push(newTodo.value)
newTodo.value = ''
}
- push로 받아온 newTodo를 todos에 넣고 초기화 해줘야한다.
- v-model로 input에 입력한 데이터를 newTodo에 받아온다.
- keyup.enter과 click으로 추가될 수 있도록 v-on을 이용한다.
<h1>Todo List</h1>
<input type="text" v-model="newTodo" @keyup.enter="addTodo">
<button @click="addTodo">ADD</button>
<p>{{todos}}</p>
입력한 후, 엔터나 ADD를 누르면 새로운 항목이 들어가는 것을 확인할 수 있다.
2. Todos에 있는 항목들 출력하기
v-for을 이용해서 출력할 수 있다!
우선 위의 입력창과 구문하기 위해 입력창은 div로 빼주고,,
리스트로 출력하므로 ul,li를 이용
v-for은 다음과 같이 사용한다
<ul>
<li v-for="todo in todos">
<p>{{todo}}</p>
</li>
</ul>
그럼 이런 결과가 나오는데..
너무 못생겼으니까 스타일을 조금만 주자
<ul style="padding: 0px;">
<li v-for="todo in todos" style="list-style-type: none;">
<input type="checkbox">
{{todo}}
</li>
</ul>
3. 리스트에서 완료한 항목은 줄 그어주기
todos에서 항목의 각각의 값이 내가 완료인지 아닌지를 가져야하므로,
js에서 addtodo함수를 살짝 수정해준다.
const addTodo = function () {
const tmp = {
text: newTodo.value,
completed: false,
}
todos.value.push(tmp)
newTodo.value = ''
}
todos에 넣을 때, 값만 넣는 것이 아니라 값+완료했는지를 같이 넣어준다
html도 수정해준다.
- style에 완료일 때의 스타일을 클래스로 만들어주고
- v-bind를 이용해서 todo.completed가 true라면 클래스를 추가해준다.
- 체크박스를 클릭하면 todo의 completed가 변해야 하므로 v-model을 이용해준다
<li v-for="todo in todos" :class="{'iscomplete':todo.completed}" style="list-style-type: none;">
<input type="checkbox" v-model="todo.completed">
{{todo.text}}
</li>
이제 완료하면 이렇게 체크가 된다
4. 항목 삭제 버튼 만들기
우선, 삭제하려면 어떤 항목을 삭제할 것인지를 알려줘야하는데 그런 값이 없다
→ 처음에 넣을 때 키값을 넣어주자 + 인덱스도 같이 넣어주자
공식문서에서 key와 인덱스를 지정하는 방법이 있음
+ 버튼에는 지우는거 넣어주기
<li v-for="(todo, index) in todos" :key="todo.id" :class="{'iscomplete':todo.completed}">
<input type="checkbox" v-model="todo.completed">
{{todo.text}}
<button @click="deleteTodo(index)">DELETE</button>
</li>
js파일에서 deleteTodo 함수 만들어주기
const deleteTodo = function (index) {
todos.value.splice(index, 1)
}
splice(index, 1) = index순서부터 1개 자르기
filter을 이용해서 하는건 html에서 deleteTodo(todo.id)로 해주고
const deleteTodo = function (id) {
todos.value = todos.value.filter((todo) => todo.id != id)
}
이렇게 해도 된다.
5. 완료 항목 전체 삭제 만들기
완료항목을 다 지우기 위해 deleteCompletedTodos함수를 만들어 준다.
const deleteCompletedTodos = function () {
// todo.completed가 true인 애들만 삭제
todos.value = todos.value.filter((todo) => {
return !todo.completed
})
}
<button @click="deleteCompletedTodos">완료 항목 삭제</button>
버튼도 만들어준다.
근데, 굳이 완료된 애들도 없는데 완료항목 삭제 버튼이 있어야할까?
6. 완료된거 없을 땐 안보이게 해주기
완료된 항목이 있나 체크하는 함수를 만들어주기 = todoCount
⭐computed 이용
기존 변수를 수정하지 않고, 계산된 값만 가지고 새로운 변수를 만들고 싶을 때!
computed 메서드 내에서 사용하는 변수가 변경이 생기면 새로 계산함!
computed를 사용하기 위해 import해오고
const { createApp, ref, computed } = Vue
const todoCount = computed(() => {
return todos.value.filter((todo) => todo.completed).length > 0
})
todo에서 completed가 true면 남겨주고, 그거의 길이가 0보다 크면, true가 되도록 리턴
그니까, todoCount가 true다? = 완료된게 하나라도 있다
그리고, 완료항목삭제 버튼에 v-if 추가해준다
<button v-if="todoCount" @click="deleteCompletedTodos">완료 항목 삭제</button>
※ 참고
v-if와 v-show의 차이
# v- if
v-if는 요소가 아예 안보임 -> 자주일어나는 일이거나, volume이 큰 요소라면 비효율적임
처음에 없다: 눈에 보이지 않아도 되는 상황이 많다면 유리
즉, 자주 변경되거나 보여야한다면 v-if는 비효율적이다
# v-show
v-show는 display: none이 되서 콘솔에서는 확인 가능
-> 자주 일어나지 않는다면 이게 오히려 비효율적임(굳이 필요없을때?)
우리 눈에 보이지 않지만, DOM에는 존재한다
즉, 안보이는 상황이 많다면 v-show가 비효율적이다.
그럼 꿋!
'FrontEnd > Vue' 카테고리의 다른 글
[Vue] Conditional Rendering(v-if, v-show) (1) | 2023.11.06 |
---|---|
[Vue] Computed 속성 (0) | 2023.11.06 |
[Vue] Form Input Bindings (0) | 2023.11.02 |
[Vue] v-on (0) | 2023.11.02 |
[Vue] v-bind (Attribute, Class, Style) (0) | 2023.11.02 |