vue add vuex
components > HelloWorld.vue
제거App.vue
에서 HelloWorld(template, import, components)와 img 관련 요소 제거store > index.js > state
state: {
todos : [
{
title : '할일 1',
completed : false,
},
{
title : '할일 2',
completed : false,
},
]
},
$store.state.변수명
형태로 store에서 값을 가져옴this.$store.state.변수명
형태<template>
<div>
<!-- 이부분 -->
<TodoListItem v-for="(todo, idx) in $store.state.todos" :key="idx" :todo="todo"/>
<!-- computed 를 사용하여 더 깔끔하게 바꾸기 -->
<TodoListItem v-for="(todo, idx) in todos" :key="idx" :todo="todo" />
</div>
</template>
<script>
import TodoListItem from "@/components/TodoListItem"
export default {
name : 'TodoList',
components : {
TodoListItem,
},
computed : { //computed 를 사용하여 더 깔끔하게 바꾸기
// todos : function(){
// return this.$store.state.todos
// }
...mapState([ // 위의 주석과 같은내용
'todos'
])
}
}
</script>
<template>
<div>
{{ todo.title }}
</div>
</template>
<script>
export default {
name : 'TodoListItem',
props : {
todo : {
type : Object
}
}
}
</script>
local한 데이터는 data 에 생성
keyup.enter 이벤트와 버튼클릭 이벤트 createTodo와 연결
todos 내용 추가
action에 createTodo 함수 만들고 context 받아옴
-> todos 내용을 수정하는 부분은 mutation쪽으로 commit (mutation의 CREATE_TODO)
mutation에 CREATE_TODO 만들고 state 받아옴 -> todos에 요소 추가
// TodoForm 부분
methods : {
createTodo : function(){
const todoItem = {
title : this.TodoTitle,
completed : false,
}
this.$store.dispatch('createTodo', todoItem) // action에 넘겨주기 - dispatch
this.TodoTitle = ""
}
}
store > index.js > actions
actions: {
createTodo : function(context, todoItem){
context.commit("CREATE_TODO", todoItem) // context 안에 commit 이 들어있음
}
},
actions: {
createTodo : function({ commit }, todoItem){ // 디스트럭처링(Destructuring) 으로 context를 commit과 state로 분해
commit("CREATE_TODO", todoItem) // context.commit => commit 으로 바꿔 쓸 수 있게 됨
}
},
store > index.js > mutation
mutations: {
CREATE_TODO : function(state, todoItem){
state.todos.push(todoItem) // state 수정
}
},
<template>
<div>
<span>{{ todo.title }}</span>
<button @click="deleteTodo">Delete</button>
</div>
</template>
<script>
export default {
name : 'TodoListItem',
props : {
todo : {
type : Object
}
},
methods : {
deleteTodo : function(){ // 메서드 추가
this.$store.dispatch('deleteTodo', this.todo)
}
}
}
</script>
mutations: {
DELETE_TODO : function(state, todoItem){
// 1. todoItem이 첫번쨰로 만나는 요소의 index를 가져옴
const index = state.todos.indexOf(todoItem)
// 2. 해당 인덱스 1개만 삭제하고 나머지 요소를 토대로 새로운 배열 생성
state.todos.splice(index, 1)
}
},
actions: {
deleteTodo : function({ commit }, todoItem){
commit("DELETE_TODO", todoItem)
}
},
template
:class="{ completed : todo.completed }"
script
style
클래스가 completed라면 취소선 그어지는 것 추가
text-decoration : line-through;
<template>
<div>
<span
@click="updateTodo"
:class="{ completed : todo.completed }"
>{{ todo.title }}</span>
<button @click="deleteTodo(todo)">Delete</button>
</div>
</template>
<script>
export default {
name : 'TodoListItem',
props : {
todo : {
type : Object
}
},
methods : {
// updateTodo : function(){
// this.$store.dispatch('updateTodo', this.todo)
// }
...mapActions([
'deleteTodo',
'updateTodo'
])
}
}
</script>
<style>
.completed {
text-decoration : line-through; /*취소선*/
}
</style>
mutations: {
UPDATE_TODO : function(state, todoItem){
state.todos = state.todos.map((todo) => {
if (todo === todoItem){
return {...todo, completed : !todo.completed}
}
return todo
})
}
actions: {
updateTodo : function({ commit }, todoItem){
commit("UPDATE_TODO", todoItem)
},
},
*변수
처럼 iterable 한 객체를 풀어서 쓰는 것...객체
const todoItem = {
todo: '첫 번째 할 일',
dueDate: '2020-12-25',
importance: 'high',
completed: false
}
// completed 값만 변경한다고 가정
//1. 첫 번째 방법
const myUpdateTodo = {
todo: '첫 번째 할 일',
dueDate: '2020-12-25',
importance: 'high',
completed: true
}
console.log(myUpdateTodo)
//2. 두 번째 방법 - 객체를 선언할 때 중복되면, 나중에 선언한 값이 덮어씌워지는 성질 이용
const myUpdateTodo2 = {
...todoItem,
completed : true,
}
console.log(myUpdateTodo2)
getters : {
completedTodosCount : function(state){
return state.todos.filter((todo) => {
return todo.completed === true
}).length
}
},
this.$store.getters.completedTodosCount
로 받아와서 쓰기<template>
<div id="app">
<h2>완료된 일 갯수 : {{ completedTodosCount }}</h2>
<TodoForm/>
<TodoList/>
</div>
</template>
<script>
import TodoForm from '@/components/TodoForm.vue'
import TodoList from '@/components/TodoList.vue'
export default {
name: 'App',
components: {
TodoForm,
TodoList
},
computed : {
// completedTodosCount : function(){
// return this.$store.getters.completedTodosCount
// }
...mapGetters([
'completedTodosCount'
])
}
</script>