전역으로 데이터를 저장하여 여러 컴포넌트에서 접근하여 사용 가능
Command 창에서 아래와 같이 명령어 수행
npm install vuex
import Vue from 'vue'; import Vuex from 'vuex' Vue.use(Vuex); export default new Vuex.Store({ state:{ todoList:[] }, // 동기적 로직 setter로 생각하면됨 mutations:{ }, // 비동기 로직 추가 시간이 오래 걸리는 작업(서버데이터 받기 , 타이머 등) actions:{ }, // 다른 컴포넌트에서 store.getters.getcounter 나 ...mapGetters 로 접근 가능 getters:{ } });
import Vue from 'vue' import App from './App.vue' import router from '@/router/router.js' import store from '@/store/index.js' Vue.config.productionTip = false new Vue({ router, store, // import한 store 추가 render: h => h(App), }).$mount('#app')
전역으로 사용할 프로퍼티를 선언 후 다른 컴포넌트나 vue 파일에서 state에서 선언된 프로퍼티 값 가져오기
state에 carList를 선언 후
import Vue from 'vue'; import Vuex from 'vuex' Vue.use(Vuex); export default new Vuex.Store({ // 전역으로 사용할 프로퍼티를 선언 state:{ carList:[ {id:1,name:'k9'}, {id:2,name:'k7'}, {id:3,name:'k3'}, ] }, });
컴포넌트에서 this.$store.state.carList 로 carList에 접근이 가능 하다
<template> <div> {{getList}} </div> </template> <script> export default { computed:{ getList(){ return this.$store.state.carList; } } } </script>
state에 선언되어있는 데이터를 변경하려면 mutations 함수를 정의하고 함수안에 state를 접근하여 변경해야 한다.
전달받을 함수명을 다음과 같이 선언 한다. ADD_CAR(state,car)
import Vue from 'vue'; import Vuex from 'vuex' Vue.use(Vuex); export default new Vuex.Store({ // 전역으로 사용할 프로퍼티를 선언 state:{ carList:[ {id:1,name:'k9'}, {id:2,name:'k7'}, {id:3,name:'k3'}, ] }, // 동기적 로직 setter로 생각하면됨 mutations:{ ADD_CAR(state,car){ console.log("ADD_CAR"); state.carList.push(car); }, DELETE_CAR(state,name){ state.carList=state.carList.filter((car)=>{ console.log(name); return car.name!=name; }); console.log(state.carList) }, }, });
컴포넌트에서 this.$store.commit() 함수를 이용하여 mutations에 선언한 함수를 호출하여 파라미터를 전달하여 store의 state의 값을 변경할 수 있다.
this.$store.commit('ADD_CAR',{name:this.inputValue});
<template> <div> <div v-for="(car,index) in carList" :key="index"> <p>car 이름{{car.name}}</p> </div> <input type="text" v-model="inputValue" placeholder="추가할 자동차 이름을 입력하세요"> <button v-on:click="addcar()">자동차 추가</button> <button @click="deleteCar()">자동차 제거</button> </div> </template> <script> export default { data(){ return { inputValue:'', carList:this.$store.state.carList, } }, methods:{ addcar(){ this.$store.commit('ADD_CAR',{name:this.inputValue}); }, deleteCar(){ this.$store.commit('DELETE_CAR',this.inputValue); } }, watch:{ '$store.state.carList':{ deep:true, handler(){ this.carList=this.$store.state.carList } } } } </script>
비동기 함수를 사용해야 할 경우 actions에 함수를 만들어 선언한다. 예를 들어 서버에서 가져온 데이터를 state에 선언 되어있는데 프로퍼티에 전달하여 사용할경우다.
store/index.js 파일에 서버로 부터 받을 함수인 getUserList() 선언 후 state의 userList에 값을 변경해야 하기 때문에 mutations 선언되어있는 ADD_USER_LIST 호출하기 위해 commit을 사용하여 전달 한다.
import Vue from 'vue'; import Vuex from 'vuex' import axios from 'axios' Vue.use(Vuex); export default new Vuex.Store({ state:{ userList:[] }, mutations:{ ADD_USER_LIST(state,users){ state.userList=users; }, }, // 비동기 로직 추가 시간이 오래 걸리는 작업(서버데이터 받기 , 타이머 등) actions:{ getUserList(context,url){ axios.get(url).then(res=>{ context.commit('ADD_USER_LIST',res.data); }); } }, });
store의 actions 선언되어있는 getUserList 호출하려면 dispatch를 사용하여 호출한다.
<template> <div> <div v-for="(user,index) in users" :key="index"> <p>{{user.name}}</p> </div> </div> </template> <script> export default { computed:{ users(){ return this.$store.state.userList; } }, created(){ this.getUserList(); }, data(){ return{ userUrl:'https://jsonplaceholder.typicode.com/users', } }, methods:{ getUserList(){ this.$store.dispatch("getUserList",this.userUrl); } } } </script>
computed와 비슷하며 state 선언되어있는 데이터를 재 가공하여 다른 컴포넌트나 vue에서 사용한다.
getters에 재 가공할 함수를 선언 후 가공된 데이터를 return 한다.
import Vue from 'vue'; import Vuex from 'vuex' import axios from 'axios' Vue.use(Vuex); export default new Vuex.Store({ state:{ userList:[] }, mutations:{ ADD_USER_LIST(state,users){ state.userList=users; }, }, actions:{ getUserList(context,url){ axios.get(url).then(res=>{ console.log(res.data); context.commit('ADD_USER_LIST',res.data); }); } }, getters:{ getFilterName(state){ return state.userList.filter(user=>{ return user.name.includes('C'); }); } } });
컴포넌트에서 computed에 store에 getters에 선언한 함수를 다음과 같이 사용가능
this.$store.getters.getFilterName
<template> <div> <div> <div v-for="user in filterList" :key="user.id"> <p>{{user.name}}</p> </div> </div> </div> </template> <script> export default { computed:{ filterList(){ return this.$store.getters.getFilterName; } }, created(){ this.getUserList(); }, data(){ return{ userUrl:'https://jsonplaceholder.typicode.com/users', } }, methods:{ getUserList(){ this.$store.dispatch("getUserList",this.userUrl); } } } </script>
모듈 파일을 다음과 같이 만들고 이름을 구분짓기 위해서 namespaced: true 추가해야 한다.
import axios from 'axios' export default{ namespaced: true, state:{ userList:[], name:'' }, mutations:{ ADD_USER_LIST(state,users){ state.userList=users; }, ADD_NAME(state,name){ state.name=name; } }, actions:{ getUserList(context,url){ axios.get(url).then(res=>{ console.log(res.data); context.commit('ADD_USER_LIST',res.data); }); } }, getters:{ getFilterName(state){ return state.userList.filter(user=>{ return user.name.includes('C'); }); } } }
3. store 선언 되어있는 index.js에 다음과 같이 modules 프로퍼티에 2번에서 만든 파일을 추가한다.
import Vue from 'vue'; import Vuex from 'vuex' import userListStore from '@/store/modules/userListStore.js' Vue.use(Vuex); export default new Vuex.Store({ modules:{ userListStore } });
아래와 같이 모듈에 등록한 userListStore 네임스페이스를 이용하여 store 내용을 수정 가져온다.
this.$store.state.userListStore.userList; this.$store.commit('userListStore/ADD_NAME','Jaewon'); this.$store.dispatch("userListStore/getUserList",this.userUrl); this.$store.getters['userListStore/getFilterName'];