“중앙에서 관리하는 모든 상태 정보(data)”
“실제로 state를 변경하는 유일한 방법”
commit()
메서드로 호출된다.“Actions를 통해 state를 조작할수 있지만 오로지 Mutations를 통해서만 하겟다.”
commit()
메서드로 호출해서 실행dispatch()
메서드로 호출된다.$ vue create todo-vuex-app
$ vue add vuex
$ yarn run serve
<todo-list-item/>
components:{TodoListItem}
<div id="app">
<h1>Todo List</h1>
<todo-form></todo-form>
<todo-list></todo-list>
</div>
components: {TodoList,TodoForm}
store/index.js 에서 state 값 만들어주기
state: {
todos:[
{
title:'할일1',
isCompleted:true,
data:new Date().getTime(),
},
{
title:'할일2',
isCompleted:false,
data:new Date().getTime(),
}
]
},
$store.state
$store.state.todos
→ store의 state의 todos를 가져오겠다.TodoList.vue
<div>
<todo-list-item
v-for="todo in **$store.state.todos**"
:key="todo.date"
/>
</div>
매 렌더링마다 가져와야 하지 않게끔 computed에 작성하는게 좋다
computed:{
todos : function(){
return this.$store.state.todos
}
}
<todo-list-item v-for="todo in todos" :key="todo.date" **:todo = "todo"**/>
TodoListItem 에서 props로 받아주기
props:{todo:Object} 이렇게도 가능하고
props:{
todo : {
type: Object 도 가능하다
}}
<template>
<div>
<input type="text"
v-model="todoTitle"
@keyup.enter="createTodo"
>
</div>
</template>
data:function(){
return {
todoTitle : '',
}
},
methods:{
createTodo: function(){
// console.log(this.todoTitle)
this.$store.commit('CREATE_TODO')
}
}
createTodo()
가 실행되는데 그 함수는this.$store.commit('CREATE_TODO’)
this.$store.commit()
을 하게 되면 mutations이 불러와진다 .mutations: {
CREATE_TODO: function(state){
console.log(state)
}
},
mutations는 무조건 첫 인자로 state를 사용해야 된다 .
여기서 state를 console 찍어보면 state의 todos 가 출력된다 →
state를 수정해도 된다라는 뜻
Commit ('호출 메서드',payload)
payload
는 보내주는 값 을 뜻한다.
methods:{
createTodo: function(){
const todoItem ={
title : this.todoTitle,
isCompleted : false,
data : new Date().getTime(),
}
// console.log(this.todoTitle)
this.$store.commit('CREATE_TODO',todoItem)
this.todoTitle = ''
}
}
todoItem 을 새로 만들어서 형태를 갖춘 뒤 , 보내준다.
mutations: {
CREATE_TODO: function(state,todoItem){
// console.log(todoItem)
state.todos.push(todoItem)
}
},
**state.todos.push(todoItem)
**완료는 됐지만, 구조가 틀리다
컴포넌트에서 사용하려면 actions를 호출해서 사용해야한다.
this.$store.dispatch('createTodo',todoItem)
actions: {
createTodo : function(**context**,todoItem){
console.log(**context**)
console.log(todoItem)
}
},
createTodo : function(context,todoItem){ context.commit('CREATE_TODO',todoItem)
CREATE_TODO
mutation 함수 호출CRAETE_TODO
함수컴포넌트에서 this.$store.dispatch()
를 통해 actions 로 이동
<button @click="deleteTodo">DELETE</button>
methods:{
deleteTodo : function(){
this.$store.dispatch('deleteTodo',this.todo)}}
actions에서 commit()
메서드를 통해 mutations 으로 이동
deleteTodo : function({commit},todoItem){
commit('DELETE_TODO',todoItem)}
mutations에서 state 관리
DELETE_TODO:function(state,todoItem){
// state.todos =state.todos.filter((todo=>(todo!==todoItem)))
const index = state.todos.indexOf(todoItem)
state.todos.splice(index,1)}
state.todos =state.todos.filter((todo=>(todo!==todoItem)))
filter 사용법
아니면 splice, indexOf 로 삭제 해주기
<span @click="updateTodo" style="cursor:grab">{{todo.title}}</span>
updateTodo : function(){
this.$store.dispatch('updateTodo',this.todo)
}
//actions
updateTodo : function({commit},todoItem){
commit('UPDATE_TODO',todoItem)
}
//mutations
UPDATE_TODO: function(state,todoItem){
state.todos = state.todos.map(todo=>{
if (todo===todoItem){
return {
...todo,
isCompleted:!todo.isCompleted }
else{return todo}})
{ ... todo, isCompleted:!todo.isCompleted}
: 같은내용 복사 하기
<span @click="updateTodo"
style="cursor:grab"
:class="{'is-completed':todo.isCompleted}"
>{{todo.title}}</span>
<style>.is-complted{text-decoration:line-through}</style>
class 를 ‘is-complted’라는 class가 todo의 isCompleted가 참일때만 부여하고 class에 스타일을 준다.
getters:{
completedTodosCount: function(state){
return state.todos.filter(todo=>{
return todo.isCompleted === true
}).length
}
},
App.vue
computed:{
completedTodosCount : function(){
return this.$store.getters.completedTodosCount
}
}
배열 조작을 쉽게 하도록 만들어 졌다.
원래 형태
computed : {
todos : function(){
return this.$store.state.todos}} 형태였는데
import {mapState} from 'vuex'
computed : mapState(['todos'])
computed : mapState(['todos'])
??? 이렇게 줄일 수 있다. computed :{
내용1,
내용2,
...mapState(['todos'])}
이런 식으로 보내면 된다. 내용이 없다면 생략해서 적는것이 최종형태 computed : { ...mapState(['todos'])}
computed:{
...mapGetters([
'completedTodosCount',
'uncompletedTodosCount',
'allCount',
])}
methods:{
...mapActions([
'deleteTodo',
'updateTodo',
])}
이걸로 끝이 아니다. 왜냐 ? 같이 보내주는 값(payload) 아래의 경우 this.todo를 처리해야한다. this.$store.dispatch('deleteTodo',this.todo)
이거는 template 상에서 보내줘야한다. <span @click="updateTodo(todo)”
<button @click="deleteTodo(todo)">DELETE</button>
설치 : $ npm i vuex-persistedstate
import createPersistedState from "vuex-persistedstate"
store({ ...
plugins:[createPersistedState()],
}