반응형
App.vue 파일에서 모두 작업하려면 너무 커지는데요. 모듈화 하여 분리할 수 있으면 다른 파일로 분리하여 나중에 코드를 파악하기도 좋게 하는 것이 좋은데요. 화면만 있다면 상관없는데 서로 데이터를 주고받아야 할 때 파일 하나로 작성하면 문제없던 일들이 분리하면서 알아야 하는 것들이 있어요.
vue create 명령어로 프로젝트를 시작했다면 components 폴더가 있고 HelloWorld.vue 파일도 예제로 있을 수 있어요. 살펴보는 것도 파악하는 과정에서 도움 받을 수 있어요. 일단 필요 없다면 지우고 원하는 파일을 추가합니다. TodoForm.vue 파일을 생성했습니다. 가장 기본 모양으로 만들어보고 App.vue 파일에서 불러와보세요.
<template>
TO DO
</template>
<script>
export default {}
</script>
파일을 만들고 나서 App.vue에서 불러와 사용해야 합니다.
import TodoForm from './components/TodoForm.vue'
export default 부분에 components를 추가하여 그 안에 넣어줘야 합니다.
export default {
components: {
TodoForm
},
setup() {
...
...
이렇게 추가하고 나면 template 영역에서 사용 가능합니다. 태그처럼 불러올 수 있어요.
<TodoForm />
파일을 분리 했을 때 setup 하는 과정에서 props와 emit을 인수로 받을 수 있어요. emit을 이용해서 호출하는 쪽으로 데이터를 전송할 수 있어요.
export default {
setup(props, context) {
const todo = ref("")
const errorMessage = ref("")
const onAdd = () => {
if(todo.value === ''){
errorMessage.value = "아무것도 입력하지 않았습니다."
} else {
context.emit("add-todo",{
id: Date.now(),
completed: false,
subject: todo.value
})
todo.value = ""
errorMessage.value = ""
}
}
return {
errorMessage,
todo,
onAdd
}
}
}
호출하는 쪽에서는 emit 첫 번째 인수에 있었던 것으로 함수 이름을 전달할 수 있어요.
<TodoForm @add-todo="onAdd" />
오류가 있는지는 모듈화한 파일에서 하고 있으니 onAdd 함수는 간단하게 작성할 수 있어요.
const onAdd = (todo) => todos.value.push(todo)
최종 코드입니다.
TodoForm.vue
<template>
<h2>TO DO</h2>
<form
@submit.prevent="onAdd"
class="d-flex"
>
<div class="flex-grow-1 mr-1">
<input
class="form-control"
type="text"
v-model="todo"
placeholder="할일을 입력하세요."
/>
</div>
<div>
<button
class="btn btn-primary"
type="submit"
>
추가
</button>
</div>
</form>
<div v-show="errorMessage!==''" class="card mt-10">
<div class="card-body p-2">
{{ errorMessage }}
</div>
</div>
</template>
<script>
import { ref } from 'vue'
export default {
setup(props, context) {
const todo = ref("")
const errorMessage = ref("")
const onAdd = () => {
if(todo.value === ''){
errorMessage.value = "아무것도 입력하지 않았습니다."
} else {
context.emit("add-todo",{
id: Date.now(),
completed: false,
subject: todo.value
})
todo.value = ""
errorMessage.value = ""
}
}
return {
errorMessage,
todo,
onAdd
}
}
}
</script>
App.vue
<template>
<div class="container">
<TodoForm @add-todo="onAdd" />
<div
v-for="(todo, index) in todos"
:key="todo.id"
class="card mt-10"
>
<div class="card-body p-2 d-flex align-items-center">
<div class="form-check flex-grow-1">
<input class="form-check-input" type="checkbox" v-model="todo.completed"/>
<label class="form-check-label" :class="{ todo: todo.completed }">
{{ todo.subject }}
</label>
</div>
<div>
<button class="btn btn-danger btn-sm" @click="deleteTodo(index)">삭제</button>
</div>
</div>
</div>
</div>
</template>
<script>
import { ref } from 'vue'
import TodoForm from './components/TodoForm.vue'
export default {
components: {
TodoForm
},
setup() {
const todos = ref([])
const todoCompletedStyle = {
textDecoration: 'line-through',
color: 'gray'
}
const onAdd = (todo) => todos.value.push(todo)
const deleteTodo = (index) => {
todos.value.splice(index,1)
}
return {
todos,
todoCompletedStyle,
onAdd,
deleteTodo
}
}
}
</script>
<style scoped>
.todo {
text-decoration: line-through;
color: gray;
}
</style>
반응형
'코딩 프로그래밍 > Javascript 자바스크립트' 카테고리의 다른 글
dom 검색해서 반복하기 getElementsByClassName loop (0) | 2023.05.26 |
---|---|
meta viewport 자바스크립트 다루기 (0) | 2023.05.19 |
Vue 배열에서 특정 요소 삭제 (0) | 2023.04.04 |
Vue style 동적 바인딩 할당 (0) | 2023.04.03 |
Vue 배열 이용한 체크박스 바인딩 (0) | 2023.04.03 |
댓글