- 데이터 주고 받기 어렵다는 것을 이전 챕터들을 하면서 깨달았다..
- 하위 컴포넌트로 전송은 props
- 상위 컴포넌트 전송은 custom event or mitt
- 이게 뭐하는 짓인가
Vuex
- 컴포넌트들이 데이터를 공유할 수 있는 javascript file
- Data를 몰아 넣는다.
- 그렇다고 남발하면 코드가 너무 복잡해지니 컴포넌트, 데이터 많을 때 사용하면 유용하다.
npm install vuex@next
import { createStore } from 'vuex'
const store = createStore({
state () {
return {
name : 'kim'
}
}
})
export default store;
- store.js가 관습인 네이밍이다. (만들어야되는 파일이다.)
- 위처럼 데이터를 넣을 수 있다.
import { createApp } from 'vue'
import App from './App.vue'
import mitt from 'mitt'
let emitter = mitt();
let app = createApp(App);
app.config.globalProperties.emitter = emitter;
import store from './store'
app.use(store).mount('#app')
- main.js
- store를 import 해서 위 처럼 mount 해준다.
- 이제 store.js에서 모든 컴포넌트들이 꺼내 쓸 수 있게된다.
<h4>안녕 {{ $store.state.name }} </h4>
- 테스트해보자.
- 위 문법이 store에 있는 것을 사용하는 문법이다.
<button @click="$store.state.name = 'Pakr' ">버튼</button>
- 버튼을 누르면 해당 데이타도 바꿔볼 수 있다 !
- ㄷㄷ
- 하지만 store.js에 있는 데이터는 이런 식으로 변경하면서 다루면 안된다는 점 명심하자.
- 컴포넌트 안에서 직접 수정하기 금지라는 것이 VueX의 국룰이다.
store Data 수정 방법 정의
- 수정하려면 store.js에 부탁하는 방법을 택해야한다.
mutations : {
nameChnage(state) {
state.name = 'park'
}
}
- mutations에 변경하는 방법을 정의해두면 된다.
- state는 위에서 정의한 state 객체를 받아온다.
<button @click="$store.commit('nameChange')">버튼</button>
- 이런식으로 이제 commit()을 정의하면 된다.
- 데이터를 이런식으로 관리하면, store.js 만 보면 되므로 디버깅 시간이 많이 줄어든다.
<h4>안녕 {{ $store.state.name }} </h4>
<button @click="$store.commit('nameChange', 'Jhon')">버튼</button>
mutations : {
nameChange(state, data) {
state.name = data;
}
}
- 이런식으로 정의해 두면 데이터를 전달 받아서 처리할 수도 있다.
actions
- store.js 에서 actions는 ajax 를 하는 곳이다.
- 또는 오래걸리는 작업들을 둔다.
actions: {
getData(context) {
console.log("clicked");
axios.get('https://codingapple1.github.io/vue/more0.json').
then((result) => {
console.log(result);
context.commit('setMore', result.data);
})
}
},
state () {
return {
name : 'kim',
likes : 0,
isClickedLike : false,
more: {},
}
},
mutations : {
setMore(state, data) {
state.more = data
},
- actions를 정의하고, 처리하고자 하는 함수를 사용하려면 mutations에 정의한다.
<p>{{ $store.state.more }}</p>
<button @click="$store.dispatch('getData')">더보기</button>
- 버튼을 누르면 dispatch라는 함수를 통해 actions가 수행이된다.
- 인자로는 실행하고자하는 actions의 function 이름을 넣어주면된다.
- 버튼을 누르면 해당 데이터들을 잘 받아오는 것을 확인할 수 있다.
- 데이터는 다른 컴포넌트에서 쓰는 것 아니면 굳이 Vuex에 저장할 이유가 없다.
- ajax 요청하려면 actions
- state 변경은 mutations
computed
- .vue 파일에서 함수를 만드는 방법은 두가지다. methods, computed
- methods는 사용할 때마다 실행된다.
- computed 함수는 사용해도 실행되지 않고 페이지 로드 시 실행 후 값을 간직한다.
- 계산결과 저장용 함수
now() {
return new Date();
}
},
computed: {
now2() {
return new Date();
}
},
- methods에 now(), computed에 now2()를 정의해보자.
<p>{{now()}} {{counter}}</p>
<button @click="counter++">버튼</button>
- 누를 때마다 counter 증가되고, 시간이 바뀌는 것을 확인할 수 있다.
<p>{{now2}} {{counter}}</p>
- now2는 한번 실행되고 데이터 계산 결과가 저장되기 때문에, ()를 안붙인다.
- 두 번째가 now2 인데, 바뀌지 않는다.
- 연산 결과를 computed에 저장해두면 자원이 절약된다.
name() {
return this.$store.state.name
}
- name이라는 함수를 지정해보자.
- store에 저장한 name을 계산한 것이다.
<p> {{ name }} </p>
...mapState(['name', 'age', 'likes']),
- 그런데 name, age 이런 식으로 빼오기는 너무 귀찮다 !
- ...mapState는 vuex 내장 함수이므로 import 해야된다.
<p> {{ name }} {{ age }} {{ likes }} </p>
- 나는 age는 정의안해서 안나오고, name, likes는 정의한대로 잘나왔다.
- state를 한번에 꺼내쓰려면 ...mapState가 유용하다.
...mapState({내이름 : 'name'})
- 이렇게하면 store의 name 데이터를 내이름이라는 변수로 데이터 바인딩 하는데 사용할 수 있다.
...mapMutations(['setMore']),
- mapMutations를 method에서 정의해주면 해당 mutations가 등록되므로 commit 이런 것을 하지 않고도 setMore() 이런식으로 갖다 쓰면된다. -> 훨씬 쉽게 store에 있던 mutations들을 쓸 수 있는 것이다. ($ 쓰기 싫을 때)