Vuex 사용 이유? 변수를 프로젝트 전체에서 사용 가능하도록 한다.
처리 흐름?
dispatch -> Actions(commit) -> Mutations -> state -> Getters
(이때, dispatch~Mutations는 데이터 반영, state~Getters는 데이터 조회 단계이다.)
사용 방법?
yarn add vuex@next // vue3에서는 vuex@next를 사용한다.
components>Notes
<template>
<ul>
<li v-for="(note, index) in notes" :key="index">{{note}}</li>
</ul>
<input type="text" v-model="title" @keypress.enter="save">
<!-- we want to push this input value into note array, so @key..-->
<!-- save는 함수다.-->
</template>
<script>
import {ref} from 'vue';
export default {
name: 'NotesComponent',
setup() {
const notes = ref([]);
const title = ref("");
function save() {
notes.value.push(title.value);
title.value="";
}
return {
notes,
title,
save,
}
}
}
</script>
router>index.js
import {createStore} from 'vuex';
const store = createStore({
state:{
title: "Vuex Store"
},
getters:{},
mutations:{},
actions:{},
});
export default store;
main.js
import { createApp } from 'vue';
import App from './App.vue';
import store from './store';
createApp(App).use(store).mount('#app')
App.vue
<template>
<h1>Vuex turitorial</h1>
{{ $store.state.title }} // 보여주기
<Notes></Notes>
<router-view></router-view>
</template>
<script>
import Notes from './components/Notes'
export default {
components: {Notes,},
setup() {
return {};
},
};
</script>
창을 띄워보면, store>index.js의 title이 화면에 찍히는 것을 확인할 수 있다.
Notes.vue
Notes.vue 컴포넌트에 import {useStore} from "vuex";를 하고,
import {computed} from 'vue'; 를 해준다.
setup() 안에 const store = useStore();를 해주고,
const notes = computed(() => store.state.notes)로 변경해준다.
변경된 Notes.vue 코드는 아래와 같다.
<template>
<ul>
<li v-for="(note, index) in notes" :key="index">{{note}}</li>
</ul>
<input type="text" v-model="title" @keypress.enter="save">
<!-- we want to push this input value into note array, so @key..-->
<!-- save는 함수다.-->
</template>
<script>
import {useStore} from "vuex";
import {computed, ref} from 'vue';
export default {
name: 'NotesComponent',
setup() {
const store = useStore();
const notes = computed(() => store.state.notes)
const title = ref("");
function save() {
notes.value.push(title.value);
title.value="";
}
return {
notes,
title,
save,
}
}
}
</script>
store>index.js
index.js도 변경해줘야 한다.
state: {} 부분에 notes: [] 코드를 추가해준다.
전체 코드는 아래와 같다.
import {createStore} from 'vuex';
const store = createStore({
state:{
title: "Vuex Store",
notes: [],
},
getters:{},
mutations:{},
actions:{},
});
export default store;
이제 받은 input 값인 title을 notes에 추가해주기로 한다. 이때 notes는 변경될 것이기 때문에 mutations를 이용한다.
그래서, Notes.vue 컴포넌트의 function을 아래와 같이 바꿔준다.
function save() {
store.commit('SAVE_NOTE', title.value);
title.value="";
}
Notes.vue의 전체 코드는 아래와 같다.
<template>
<ul>
<li v-for="(note, index) in notes" :key="index">{{note}}</li>
</ul>
<input type="text" v-model="title" @keypress.enter="save">
<!-- we want to push this input value into note array, so @key..-->
<!-- save는 함수다.-->
</template>
<script>
import {useStore} from "vuex";
import {computed, ref} from 'vue';
export default {
name: 'NotesComponent',
setup() {
const store = useStore();
const notes = computed(() => store.state.notes)
const title = ref("");
function save() {
store.commit('SAVE_NOTE', title.value);
title.value="";
}
return {
notes,
title,
save,
}
}
}
</script>
물론, store>index.js도 변경해줘야 한다. mutations 부분이 수정되었다.
import {createStore} from 'vuex';
const store = createStore({
state:{
title: "Vuex Store",
notes: [],
},
getters:{},
mutations:{
SAVE_NOTE(state, title) {
state.notes.push(title)
}
},
actions:{},
});
export default store;
여기까지 이해가 되었다면, 아래와 같이 한번 더 수정을 해준다. save 함수와 actions 부분이 변경된 것을 확인할 수 있다.
Notes.vue
<template>
<ul>
<li v-for="(note, index) in notes" :key="index">{{note}}</li>
</ul>
<input type="text" v-model="title" @keypress.enter="save">
<!-- we want to push this input value into note array, so @key..-->
<!-- save는 함수다.-->
</template>
<script>
import {useStore} from "vuex";
import {computed, ref} from 'vue';
export default {
name: 'NotesComponent',
setup() {
const store = useStore();
const notes = computed(() => store.state.notes)
const title = ref("");
function save() {
store.dispatch('saveNote', title.value);
title.value="";
}
return {
notes,
title,
save,
}
}
}
</script>
index.vue
import {createStore} from 'vuex';
const store = createStore({
state:{
title: "Vuex Store",
notes: [],
},
getters:{},
mutations:{
SAVE_NOTE(state, title) {
state.notes.push(title)
}
},
actions:{
saveNote({commit}, title) {
commit('SAVE_NOTE', title)
}
},
});
export default store;
이번에는 getters를 사용해보겠다.
store>index.js에서 getters 부분이 수정되었다. totalNote를 계산해보기 위해 computed를 사용했다.
import {createStore} from 'vuex';
const store = createStore({
state:{
title: "Vuex Store",
notes: [],
},
getters:{
totalNotes(state) {
return state.notes.length
}
},
mutations:{
SAVE_NOTE(state, title) {
state.notes.push(title)
}
},
actions:{
saveNote({commit}, title) {
commit('SAVE_NOTE', title)
}
},
});
export default store;
Notes.vue
Notes.vue setup(){} 안에
const totalNotes = computed(() => store.getters.totalNotes)
코드를 추가해준 후,
template 태그에서
Total Notes : {{totalNotes}}
를 보여준다.<template>
<ul>
<li v-for="(note, index) in notes" :key="index">{{note}}</li>
</ul>
<input type="text" v-model="title" @keypress.enter="save">
<!-- we want to push this input value into note array, so @key..-->
<!-- save는 함수다.-->
<p>Total Notes : {{totalNotes}}</p>
</template>
<script>
import {useStore} from "vuex";
import {computed, ref} from 'vue';
export default {
name: 'NotesComponent',
setup() {
const store = useStore();
const notes = computed(() => store.state.notes)
const totalNotes = computed(() => store.getters.totalNotes)
const title = ref("");
function save() {
store.dispatch('saveNote', title.value);
title.value="";
}
return {
notes,
title,
save,
totalNotes,
}
}
}
</script>
마지막으로 component를 나눠봤다.
components 폴더에 AddNewNote.vue를 생성하고, 코드를 분리했다.
AddNewNote.vue
<template>
<div>
<input type="text" v-model="title" @keypress.enter="save">
<!-- we want to push this input value into note array, so @key..-->
<!-- save는 함수다.-->
<p>Total Notes : {{totalNotes}}</p>
</div>
</template>
<script>
import {useStore} from "vuex";
import {computed, ref} from 'vue';
export default {
name: 'NotesComponent',
setup() {
const store = useStore();
const totalNotes = computed(() => store.getters.totalNotes)
const title = ref("");
function save() {
store.dispatch('saveNote', title.value);
title.value="";
}
return {
title,
save,
totalNotes,
}
}
}
</script>
Notes.vue
<template>
<AddNewNote></AddNewNote>
<ul>
<li v-for="(note, index) in notes" :key="index">{{note}}</li>
</ul>
</template>
<script>
import AddNewNote from "@/components/AddNewNote";
import {useStore} from "vuex";
import {computed,} from 'vue';
export default {
name: 'NotesComponent',
components: {AddNewNote},
setup() {
const store = useStore();
const notes = computed(() => store.state.notes)
return {
notes,
}
}
}
</script>
store>index.js
import {createStore} from 'vuex';
const store = createStore({
state:{
title: "Vuex Store",
notes: [],
},
getters:{
totalNotes(state) {
return state.notes.length
}
},
mutations:{
SAVE_NOTE(state, title) {
state.notes.push(title)
}
},
actions:{
saveNote({commit}, title) {
commit('SAVE_NOTE', title)
}
},
});
export default store;