// search.vue 의 methods 의 apply 를 수정한다.
methods: {
async apply() {
// dispatch 는 movies.js 의 actions 를 실행한다.
// 첫번째 인수의 movie/ 는 store/index.js 의 movie 다.
// 두번째 인수는 payload 에 들어갈 객체이다.
this.$store.dispatch('movie/searchMovies', {
title: this.title,
type: this.type,
number: this.number,
year: this.year
})
}
}
// store/movie.js 수정. 실제 프로젝트용으로 다시 아래에서 수정
import axios from 'axios'
export default {
// module화 해서 사용 될 수 있다를 명시적으로 나타낸다.
namespaced: true,
// data
state: () => ({
movies: [],
message: '',
loading: false,
}),
// computed
getters: {},
// methods
// mutations : 데이터를 변경할 수 있는 장소다..
mutations: {
updateState(state, payload) {
// 반환값은 ['movies', 'mesage', 'loading']
Object.keys(payload).forEach(key => {
state[key]= payload[key]
})
},
resetMovies(state) {
state.movies = []
}
},
// 비동기로 처리된다.
actions: {
// state 접근하기 위해서 위와는 다르게 context 로 접근한다.
async searchMovies(context, payload) {
const { title, type, number, year } = payload
// Search Movies!
const OMDB_API_KEY = '7035c60c'
const res = await axios.get(`https://www.omdbapi.com/?apikey=${OMDB_API_KEY}&s=${title}&type=${type}&y=${year}&page=1`)
const { Search, totalResult } = res.data
// commit 은 mutation 을 실행시킨다. 두번째 인수로 객체를 넘겨주면 mutaions 에서 payload 로 받는다.
context.commit('updateState', {
movies: Search,
message: 'Hello',
loading: true,
})
}
}
}
actions: {
async searchMovies({ commit }, payload) {
const { title, type, number, year } = payload
const OMDB_API_KEY = '7035c60c'
const res = await axios.get(`https://www.omdbapi.com/?apikey=${OMDB_API_KEY}&s=${title}&type=${type}&y=${year}&page=1`)
const { Search, totalResult } = res.data
commit('updateState', {
movies: Search,
})
}
}
Search.vue 에서 엔터키나 apply 를 누르게 되면!!
store/index 를 거쳐서 movie 모듈로 접근하고
store/movie 에서 actions 의 searchMovies 가 실행된다!
OMDbapi 에 요청이 들어가고 결과를 res 로 받아서 데이터를
const { Search, totalResult } 로 받아주고!
context 를 객체구조분해로 필요한 commit 만 사용해 주고, commit 으로
mutations의 undateState 를 실행한다. 그리고 data인 state 를 갱신 시켜주는 것이다.
최종적으로 이렇게 갱신된 데이터는 MovieList.vue 에서 사용하고
MovieList 에서 for문을 돌려 List 각각의 요소를 MovieItem.vue 에서 출력한다.
// MovieList.vue
// v-for 의 movie를 MovieItem 에 props 로 :movie="movie" 로 넘겨준다.
<template>
<div class="container">
<div class="inner">
<MovieItem
v-for="movie in movies"
:key="movie.imdbID"
:movie="movie" />
</div>
</div>
</template>
<script>
import MovieItem from '~/components/MovieItem'
export default {
components: {
MovieItem
},
computed: {
movies() {
// movie 모듈안에 movies
// 반응성 데이터를 유지하기 위해 computed
// movie 모듈에서 movies 데이터 return
return this.$store.state.movie.movies
}
}
}
</script>
//MovieItem.vue
<template>
<div>{{ movie.Title }}</div>
</template>
<script>
export default {
props: {
movie: {
type: Object,
// type of the default value for 'movie' prop must be a function
// default: {} **error!!**
// 객체 데이터나 배열 데이터 같은 참조형 데이터는 데이터가 가변할 수 있다.
// 따라서 직접사용이 아닌 함수로 만들어서 반환한다.
default: () => ({})
}
}
}
</script>