nuxt.js가 Vuex 구현하는 핵심 이유는, 저장소를 사용하여 상태를 관리하는 것은 모든 대형 애플리케이션에서 중요하기 때문입니다.
Nuxt.js는 store 디렉토리를 바라보고 있습니다. 만약 store
디렉토리가 존재한다면:
1. Vuex를 불러옵니다.
2. 벤더 번들에 vuex
모듈을 추가합니다.
3. 루트 Vue
인스턴스에 store
옵션을 추가합니다.
Nuxt.js 에서는 2가지 store 모드를 지원하며, 선호하는 모드를 사용합니다.
store/index.js
에서 store 인스턴스를 return 합니다.클래식 모드를 사용하려면 store/index.js
파일을 만들고 store 인스턴스를 export 하면 됩니다.
import Vuex from 'vuex'
const store = () => new Vuex.Store({
state: {
counter: 0
},
mutations: {
increment (state) {
state.counter++
}
}
})
export default store
nuxt.js에 vuex
가 포함되어 있기 때문에 따로 설치할 필요 없습니다.
이제 컴포넌트에서 this.%store
를 사용할 수 있습니다.
<template>
<button @click="$store.commit('increment')">{{ $store.state.counter }}</button>
</template>
Nuxt.js는 store
디렉토리에서 모든 모듈을 관리할 수 있도록 해줍니다.
만약 모듈 모드를 원한다면 store/index.js
파일에 store 인스턴스 대신 state와 mutations, actions 를 export 합니다.
export const state = () => ({
counter: 0
})
export const mutations = {
increment (state) {
state.counter++
}
}
이제 store/todos.js
파일을 만들 수 있습니다.:
export const state = () => ({
list: []
})
export const mutations = {
add (state, text) {
state.list.push({
text: text,
done: false
})
},
remove (state, { todo }) {
state.list.splice(state.list.indexOf(todo), 1)
},
toggle (state, todo) {
todo.done = !todo.done
}
}
store는 아래와 같이 생성될 것입니다:
new Vuex.Store({
state: { counter: 0 },
mutations: {
increment (state) {
state.counter++
}
},
modules: {
todos: {
state: {
list: []
},
mutations: {
add (state, { text }) {
state.list.push({
text,
done: false
})
},
remove (state, { todo }) {
state.list.splice(state.list.indexOf(todo), 1)
},
toggle (state, { todo }) {
todo.done = !todo.done
}
}
}
}
})
이제 pages/todos.vue
컴포넌트에서 todos
모듈을 사용해보겠습니다:
<template>
<ul>
<li v-for="todo in todos">
<input type="checkbox" :checked="todo.done" @change="toggle(todo)">
<span :class="{ done: todo.done }">{{ todo.text }}</span>
</li>
<li><input placeholder="What needs to be done?" @keyup.enter="addTodo"></li>
</ul>
</template>
<script>
import { mapMutations } from 'vuex'
export default {
computed: {
todos () { return this.$store.state.todos.list }
},
methods: {
addTodo (e) {
this.$store.commit('todos/add', e.target.value)
e.target.value = ''
},
...mapMutations({
toggle: 'todos/toggle'
})
}
}
</script>
<style>
.done {
text-decoration: line-through;
}
</style>
fetch 메소드는 페이지를 렌더링하기 전에 store를 채우기 위해서 사용됩니다. 컴포넌트의 data를 설정하지 않는다는 점을 빼고는 data 메소드와 비슷합니다.
만약 store에 nuxtServerInit
가 정의되면, nuxt.js는 서버사이드에서 context와 함께 이 함수를 호출합니다. 이는 서버에서 받은 데이터를 클라이언트로 직접 전달할 때 유용합니다.
예를 들어, 서버에서 세션을 가지고 있다면 req.session.user로 접근이 가능합니다. store로 유저의 인증 정보를 전달하기 위해서는 store/index.js
를 아래와 같이 수정합니다.
actions: {
nuxtServerInit ({ commit }, { req }) {
if (req.session.user) {
commit('user', req.session.user)
}
}
}