2022. 4. 1. 23:28ㆍVue
1. index.html
getbootstrap.com 들어가서 css link 복사해서 연결해준다.
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/css/bootstrap.min.css" integrity="sha384-zCbKRCUGaJDkqS1kPbPd7TveP5iyJE0EjAuZQTgFLD2ylzuqKfdKlfG/eSrtxUkn" crossorigin="anonymous">
2.컴포넌트 연결하기 / v-for문 돌리기
components 파일에서 Todo.vue 컴포넌트 만들고 연결해준다.
// App.vue 부모
<template>
<div id="app" class="container">
<h1 class="text-center">Todo App</h1>
<input type="text" class="w-100 p-2" placeholder="Type todo">
<hr>
<Todo v-for="todo in todos"
:key="todo.id">
</Todo>
</div>
</template>
<script>
import Todo from "@/components/Todo"
export default {
components: {Todo},
data() {
return {
todos: [
{id: 1, text: 'study hard', checked: true},
{id: 2, text: 'buy a car', checked: false},
]
}
},
}
</script>
// Todo.vue 자식
<template>
<div>
<input type="checkbox">
<span class="ml-3">Buy a car</span>
</div>
</template>
<script>
export default {
name: "Todo",
}
</script>
:todo="todo" 로 하고 props에 todo로 받아와도 되는데 구분을 하기 위해 나는 :todoList로 바인딩을 해주었다.
App.vue 에서 v-for문을 도는데 Todo.vue (자식) 컴포넌트에 데이터를 넘겨 줘야한다. 그래서 props로 데이터를 전달받아서 뿌려줌 !
체크 박스도 전달 받아야겠지????
=> :checked="todoList.checked" 해주고 true면 체킹이 되어진다.
3. @keyup.enter 이벤트 추가 하기
<template>
<div id="app" class="container">
<h1 class="text-center">Todo App</h1>
<input type="text"
class="w-100 p-2"
placeholder="Type todo"
@keyup.enter="addTodo">
<hr>
<Todo v-for="todo in todos"
:key="todo.id"
:todoList="todo">
</Todo>
</div>
</template>
<script>
import Todo from "@/components/Todo"
export default {
components: {Todo},
data() {
return {
todos: [
{id: 1, text: 'study hard', checked: true},
{id: 2, text: 'buy a car', checked: false},
]
}
},
methods: {
addTodo(e) {
this.todos.push(
{id: Math.random(),
text: e.target.value,
checked: false}
)
},
}
}
</script>
4. input 에 글쓰고 난 후 비워주기
<template>
<div id="app" class="container">
<h1 class="text-center">Todo App</h1>
<input type="text"
v-model="clearText"
class="w-100 p-2"
placeholder="Type todo"
@keyup.enter="addTodo">
<hr>
<Todo v-for="todo in todos"
:key="todo.id"
:todoList="todo">
</Todo>
</div>
</template>
<script>
import Todo from "@/components/Todo"
export default {
components: {Todo},
data() {
return {
clearText: '',
todos: [
{id: 1, text: 'study hard', checked: true},
{id: 2, text: 'buy a car', checked: false},
]
}
},
methods: {
addTodo(e) {
this.todos.push({
id: Math.random(),
text: e.target.value,
checked: false
});
this.clearText = ''
},
}
}
</script>
input 에 v-model 써주고, data에 넣고, @keyup.enter 메소드 안에서 push 한 다음, this.clearText= ''로 초기화 시키기
5. emit으로 값 전달해주기
todoList.checked 출력된 값이 있고 체크박스를 클릭했다 안했다하면 true 에서 false로 값이 바뀌지 않는다.
그래서 이것을 바뀌도록 하는 작업이 필요하다.
// Todo.vue 자식컴포넌트
<template>
<div>
{{ todoList.checked}}
<input type="checkbox"
:checked="todoList.checked"
@change="toggleCheckbox">
<span class="ml-3">{{ todoList.text }}</span>
</div>
</template>
<script>
export default {
name: "Todo",
props: {
todoList: {
type: Object,
required: true,
}
},
methods: {
toggleCheckbox(e) {
this.$emit('toggle-checkbox', {
id: this.todoList.id,
checked: e.target.checked
})
}
}
}
</script>
@change="toggleCheckbox" 체인지 이벤트를 만들고 부모한테 값을 넘겨주기
객체로 value값을 넘긴거라서 App.vue에서는 구조분해 할당으로 { id, checked }로 value값을 받아 와야 한다.
$emit으로 보낸 것을 부모에서는 @toggle-checkbox 로 기입
>> 자꾸 : 이걸로 쓰는 데 @ 쓰기!!!!!!!!!!!!!!!!!!!!!
// App.vue 부모
<template>
<div id="app" class="container">
<h1 class="text-center">Todo App</h1>
<input type="text"
v-model="clearText"
class="w-100 p-2"
placeholder="Type todo"
@keyup.enter="addTodo">
<hr>
<Todo v-for="todo in todos"
:key="todo.id"
:todoList="todo"
@toggle-checkbox="toggleCheckbox">
</Todo>
</div>
</template>
<script>
import Todo from "@/components/Todo"
export default {
components: {Todo},
data() {
return {
clearText: '',
todos: [
{id: 1, text: 'study hard', checked: true},
{id: 2, text: 'buy a car', checked: false},
]
}
},
methods: {
addTodo(e) {
this.todos.push(
{id: Math.random(),
text: e.target.value,
checked: false}
);
this.clearText = ''
},
toggleCheckbox({id, checked}) {
const index = this.todos.findIndex( todo => {
return todo.id === id;
})
this.todos[index].checked = checked;
}
}
}
</script>
id랑 같은거 찾아서 index 를 알아내고, 그 인덱스에서 checked 되어있는지도 값 받아와서 ...
checkbox 클릭하면 false > true / true > false로 변경된다.
6. checkbox true 이면 밑줄 그어 주기
:class, :style 바인딩
// todo.vue
<template>
<div>
{{ todoList.checked}}
<input type="checkbox"
:checked="todoList.checked"
@change="toggleCheckbox">
<span class="ml-3"
:class="todoList.checked ? 'text-muted' : ''"
:style="todoList.checked ? 'text-decoration:line-through' : ''">
{{ todoList.text }}
</span>
</div>
</template>
<script>
export default {
name: "Todo",
props: {
todoList: {
type: Object,
required: true,
}
},
methods: {
toggleCheckbox(e) {
this.$emit('toggle-checkbox', {
id: this.todoList.id,
checked: e.target.checked
})
}
}
}
</script>
7. delete 버튼 추가
// Todo.vue
<template>
<div class="mb-2 d-flex">
<div>
<input type="checkbox"
:checked="todoList.checked"
@change="toggleCheckbox">
</div>
<span class="ml-3 flex-grow-1"
:class="todoList.checked ? 'text-muted' : ''"
:style="todoList.checked ? 'text-decoration:line-through' : ''">
{{ todoList.text }}
</span>
<button class="btn btn-danger btn-sm"
@click="clickDelete">delete
</button>
</div>
</template>
<script>
export default {
name: "Todo",
props: {
todoList: {
type: Object,
required: true,
}
},
methods: {
toggleCheckbox(e) {
this.$emit('toggle-checkbox', {
id: this.todoList.id,
checked: e.target.checked
})
},
clickDelete() {
this.$emit('click-delete', this.todoList.id)
}
}
}
</script>
// App.vue
<template>
<div id="app" class="container">
<h1 class="text-center">Todo App</h1>
<input type="text"
v-model="clearText"
class="w-100 p-2"
placeholder="Type todo"
@keyup.enter="addTodo">
<hr>
<Todo v-for="todo in todos"
:key="todo.id"
:todoList="todo"
@toggle-checkbox="toggleCheckbox"
@click-delete="clickDelete">
</Todo>
</div>
</template>
<script>
import Todo from "@/components/Todo"
export default {
components: {Todo},
data() {
return {
clearText: '',
todos: [
{id: 1, text: 'study hard', checked: true},
{id: 2, text: 'buy a car', checked: false},
]
}
},
methods: {
addTodo(e) {
this.todos.push(
{id: Math.random(),
text: e.target.value,
checked: false}
);
this.clearText = ''
},
toggleCheckbox({id, checked}) {
const index = this.todos.findIndex( todo => {
return todo.id === id;
})
this.todos[index].checked = checked;
},
clickDelete(id) {
const index = this.todos.findIndex( todo => {
return todo.id === id
});
this.todos.splice(index, 1)
}
}
}
</script>
filter 메소드 사용 하는 경우
clickDelete(id) {
// const index = this.todos.findIndex( todo => {
// return todo.id === id
// });
// this.todos.splice(index, 1)
this.todos = this.todos.filter(todo => todo.id !== id)
}
'Vue' 카테고리의 다른 글
Bootstrap 적용하기 (0) | 2022.04.13 |
---|---|
Vue Router - prefetch, Lazy Loading(지연된 로딩) (0) | 2022.04.07 |
[Vue] Props Emit 부모 자식 간에 데이터 주고 받기 (3) | 2022.03.18 |
[Vue] Slot (0) | 2022.03.17 |
[Vue] 인코딩 / 디코딩 (0) | 2022.03.15 |