Skip to content

Instantly share code, notes, and snippets.

@nuria-fl
Created June 30, 2017 17:15
Show Gist options
  • Save nuria-fl/493fda154acf06f9733821db5a6cda1a to your computer and use it in GitHub Desktop.
Save nuria-fl/493fda154acf06f9733821db5a6cda1a to your computer and use it in GitHub Desktop.
Vue tutorial: Vuex
<template>
<div>
<header v-if="genres.length" class="header">
<dropdown
filterName="genre"
:items="genres"
:selected.sync="selectedGenre">
</dropdown>
</header>
<div v-if="movies.length" class="movies">
<movie v-for="movie in filteredMovies" :movie="movie">
</movie>
</div>
</div>
</template>
<script>
import { mapState, mapActions } from 'vuex'
import api from '../services/api'
import dropdown from './Dropdown'
import movie from './Movie'
export default {
name: 'hello',
data () {
return {
selectedGenre: null
}
},
computed: {
...mapState([
'movies',
'genres'
]),
filteredMovies() {
if (this.selectedGenre) {
const genre = parseInt(this.selectedGenre)
return this.movies.filter( movie => {
return movie.genre_ids.indexOf(genre) !== -1
})
} else {
return this.movies
}
}
},
methods: {
...mapActions([
'getMovies',
'getGenres'
])
},
created () {
this.getMovies()
this.getGenres()
},
components: {
dropdown,
movie
}
}
</script>
// src/store/index.js
import Vue from 'vue';
import Vuex from 'vuex';
import api from '../services/api';
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
movies: [],
genres: []
},
getters: {
},
mutations: {
addMovie (state, movie) {
state.movies.push(movie)
},
addGenre (state, genre) {
state.genres.push(genre)
},
saveMovie (state, movieId) {
const movieIdx = state.movies.findIndex(movie => movie.id === movieId)
const updatedMovie = Object.assign({}, state.movies[movieIdx], {saved: true})
state.movies.splice(movieIdx, 1, updatedMovie)
}
},
actions: {
getMovies ({ state, commit }) {
if(!state.movies.length) {
api.getMovies()
.then( data => {
data.forEach(movie => commit('addMovie', movie))
})
}
},
getGenres ({ state, commit }) {
if(!state.genres.length) {
api.getGenres()
.then( data => {
data.forEach(genre => commit('addGenre', genre))
})
}
}
}
})
export default store;
// src/main.js
import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store'
Vue.config.productionTip = false
new Vue({
el: '#app',
router,
store,
template: '<App/>',
components: { App }
})
<template lang="html">
<article class="movies__item">
<button class="movies__like" @click="saveMovie(movie.id)">
<i :class="movie.saved ? 'fa fa-check' : 'fa fa-star'"></i>
</button>
<img :src="`https://image.tmdb.org/t/p/w500/${movie.poster_path}`" alt="">
</article>
</template>
<script>
import { mapMutations } from 'vuex'
export default {
props: ['movie'],
methods: {
...mapMutations([
'saveMovie'
])
}
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment