
➜ 인프런 코지코더 기초강의 듣고 적기
요약 :
① Vue.js 기초(3)의 ④번과 반대되는 props를 넣어 처리
② To-Do 삭제하기
③ emits
④ To-Do 검색
props는 단방향 바인딩, 자식 ➜ 부모 값 변경X
TodoList 컴포넌트 사용시, 속성으로 원하는 이름적고 바인딩을 하면 원한느 데이터를 보낼수 있음
<TodoList :todos="todos"></TodoList>
:todos - props로 보내는이름
"todos" - 보낼데이터
@ TodoList 컴포넌트
export default{
props:["todos"]
}
props:["todos"] - props로 todos를 받아옴 (template에 todos 접근가능)
<script>
export default{
props:{
todos:{
type:Array,
required:true,
}
}
}
</script>
type : Array - todos가 array이기 때문에 받는 타입 array로 설정
required : true - TodoList에는 항상 todo array가 필요하여 required:true가 필요
∴ type : string, number, boolean, array, object, function, promise
// app.vue
<template>
<div class="container">
<h2>To-Do List</h2>
<TodoSimpleForm @add-todo="addTodo"></TodoSimpleForm>
<div v-if="!todos.length">추가된 Todo가 없습니다.</div>
<TodoList
:todos="todos"
@delete-todo="deleteTodo"
></TodoList>
</div>
</template>
<script>
import { ref } from 'vue';
import TodoSimpleForm from "@/components/TodoSimpleForm.vue";
import TodoList from "@/components/TodoList.vue";
export default {
components: {
TodoSimpleForm,
TodoList
},
setup(){
// App.vue에서 모든 todos를 관리할 예정 - todos데이터를 TodosList로 패스하기
const todos = ref([]);
const addTodo = (todo) => {
todos.value.push(todo);
};
const deleteTodo = (index) => {
todos.value.splice(index,1);
};
return{
todos,
addTodo,
deleteTodo,
};
}
}
</script>
// TodoList.vue
<template>
<div
v-for="(todo, index) in todos"
:key="todo.id"
class="card mt-2"
>
<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.complated"
>
<label
class="form-check-label"
:class="{todo : todo.complated}"
>
{{ todo.subject }}
</label>
</div>
<div>
<button
class="btn btn-danger btn-sm"
@click="deleteTodo1(index)"
>
Delete
</button>
</div>
</div>
</div>
</template>
<script>
export default {
// props:['todos'] // 앞에 있는 이름 (props로 보내는 이름) - 컴포넌트에서 props에서 todos로 받아오는구나를 알게됨, template에서 todos에 접근가능
props:{
todos:{
type: Array, // todos가 array이기때문에 받는 타입을 array로 설정
// type에는 string,number,boolean,array,object,function,promise
required: true // todolist에는 항상 todo array가 필요하여 required : true
}
},
setup(props,context){
const deleteTodo1 = (index) => {
context.emit('delete-todo',index)
}
return{
deleteTodo1,
}
}
}
</script>
여기서 각 영역에 deleteTodo는 서로를 함수호출하여 사용한다.
props:["todos"] 와 동일하게 작업처리하는 방법
emits:[ 이벤트 이름 ]
↪ 넣어주면 좋은점 : emit가 여러군데 퍼져있을 경우, 모아두면 한눈에 확인하기 쉽다.
<script>
export default{
setup(prop,context){
const toggleTodo = (index) =>{
context.emit('toggle-todo',index);
}
const DeleteTodo = (index) =>{
context.emit('delete-todo',index);
}
}
}
</script>
context는 객체를 보내준다. 객체구조분해 emit만 빼오면 context사용하지않고 바로 emit 사용할 수 있음
↓ 해당 내용처럼 바꿔어 사용해줄 수 있음
<script>
export default{
setup(prop,{ emit }){
const toggleTodo = (index) =>{
emit('toggle-todo',index);
}
const DeleteTodo = (index) =>{
emit('delete-todo',index);
}
}
}
</script>
<template>
<div class="container">
<h2>To-Do List</h2>
<input
class="form-control"
type="text"
v-model="searchText"
placeholder="Search"
>
<hr>
<TodoSimpleForm @add-todo="addTodo"></TodoSimpleForm>
<div v-if="!filteredTodos.length">
There is nothing to display.
</div>
<TodoList
:todos="filteredTodos"
@toggle-todo="toggleTodo"
@delete-todo="deleteTodo"
></TodoList>
</div>
</template>
<script>
import { ref, computed } from 'vue';
export default {
setup(){
const todos = ref([]);
const searchText = ref('');
const filteredTodos = computed(() => {
if(searchText.value.length > 0){// 만약에 searchText가 빈칸이 아니라면,
return todos.value.filter(todo => {
return todo.subject.includes(searchText.value)
});
}else{ // 빈칸일 경우
return todos.value;
}
});
return{
todos,
searchText,
filteredTodos,
};
}
}
</script>
const filteredTodos = computed(() => {}
↪ filteredTodos는 계산된 속성 | computed속성은 내부값이 변화할때 자동으로 재계산되며, 캐싱기능이 있어 성능최적화에 유리함
if(searchText.value.length > 0){} // 빈칸이 아닐경우
↪ 사용자가 searchText라는 입력필드에 텍스트 입력여부를 확인하고,
searchText.value.length는 searchText의 길이를 반환 | 길이가 0보다 크면 if값이 실행됨
return todos.value.filter(todo => {})
↪ todos는 반응형 배열, 여러할일(todo)객체를 담고있음
특정조건을 만족하는 항목만 필터링하여 새로운 배열로 반환, filter메서드는 배열의 각요소를 검사하여 true만 반환

return todo.subject.includes(searchText.value)
↪ 각 todo객체의 subject가 searchText를 포함하는지 검사한다.
includes메서드는 특정문자열이 포함되어 있으면 true를 반환한다.
searchText.value의 내용이 subject안에 포함된 항목만 필터링함

↪ 해당내용이 없을경우

↪ 검색입력창이 공란일 경우
else { return todos.value; }
↪ 만약 searchText가 빈문자열이라면, 모든 todos를 그대로 반환한다.
즉, 검색어가 없을경우 필터링없이 전체목록을 보여준다.