The Pokedex Project — Integrando Vuex a los componentes. (6)
En la publicación pasada integramos Vue a nuestras vistas, ahora hay que refactorizar un poco el código de los componentes y para ello integraremos Vuex que es un administrador de estados de componentes.
Puedes revisar la publicación anterior aquí:
Creamos el directorio “store” en “resources/js” y los siguientes archivos dentro del directorio “store”: store.js, state.js, getters.js, mutations.js y actions.js.
En el archivo store.js colocamos lo siguiente:
import state from "./state"
import getters from "./getters"
import mutations from "./mutations"
import actions from "./actions"
const store = new Vuex.Store({
state,
getters,
mutations,
actions,
})export default store
En el archivo state.js colocamos lo siguiente:
export default {
pokemons: [],
}
En el archivo getters.js colocamos lo siguiente:
export default {
POKEMONS: state => {
return state.pokemons
},
}
En el archivo mutations.js colocamos lo siguiente:
export default {
SET_POKEMONS(state, data) {
state.pokemons = data
},
}
En el archivo actions.js colocamos lo siguiente:
export default {
getPokemonsData: async (context, payload) => {
try {
let { data } = await axios.get('/pokemons')
context.commit('SET_POKEMONS', data)
} catch (e) {
console.log(e)
}
},
}
Teniendo nuestros archivos del “store” de Vuex programados, importaremos “store.js” al componente “PokedexContent.vue”, quitamos el método getPokemonsData() de “methods” y lo reemplazamos por el método del mismo nombre pero en actions del store.
Por último hacemos una propiedad “computed” del componente y lo relacionamos con el state del store, y quitamos también data() del componente.
El archivo debería de quedar
<template>
<div class="grid grid-cols-3 gap-4">
<the-item-data v-for="item in items" :data-item="item" :key="item.code" />
</div>
</template>
<script>
import store from "../store/store"
import TheItemData from "./TheItemData";
export default {
name: "PokedexContent",
components: {
'the-item-data': TheItemData,
},
created() {
this.store.dispatch('getPokemonsData')
},
store,
computed: {
items: {
get () {
return this.$store.getters.POKEMONS
},
set (value) {
this.$store.commit('SET_POKEMONS', value)
}
},
},
}
</script>
Compilamos nuestros archivos de JS y deberíamos de ver el mismo resultado en la vista, ahora nuestra vista ya maneja los estados de los componentes con Vuex.
Agregando un Buscador para los Pokemons.
Con la ayuda de Vuex agregaremos un Search Bar para buscar nuestros Pokemones por el nombre.
Esta característica ya la habíamos visto en las series del Pokedex con PHP Vanilla. Así que simplemente copiaremos el mismo componente.
Creamos el archivo en “resources/js/componentes” y lo nombramos “TheSearchBox”, y colocamos lo siguiente:
<template>
<div class="m-5">
<input
v-model="searchInput"
type="search"
name="query"
placeholder="Find your Pokemon ..."
required="required"
class="p-4 text-gray-700 w-full bg-white border border-gray-300 rounded-lg focus:outline-none focus:border-gray-400">
</div>
</template>
<script>
export default {
name: "TheSearchBox",
data () {
return {
searchInput: ''
}
},
computed: {
dataList: {
get () {
return this.$store.getters.POKEMONS
},
set (value) {
this.$store.commit('SET_POKEMONS', value)
}
},
filterDataList: {
get () {
return this.$store.getters.POKEMONS_WITH_SEARCH_FILTER
},
set (value) {
this.$store.commit('SET_POKEMONS_WITH_SEARCH_FILTER', value)
}
}
},
watch: {
searchInput: {
handler: function (value) {
this.filterListByInputSearch()
},
},
},
methods: {
filterListByInputSearch() {
if (this.searchInput !== '') {
let searchDataList = this.filterDataList.filter(pokemon => pokemon.name.toLowerCase().includes(this.searchInput.toLowerCase()))
if (searchDataList.length === 1) {
searchDataList = this.dataList.filter(pokemon => pokemon.name.toLowerCase().includes(this.searchInput.toLowerCase()))
}
this.$store.commit('SET_POKEMONS_WITH_SEARCH_FILTER', searchDataList)
} else {
this.$store.commit('SET_POKEMONS_WITH_SEARCH_FILTER', this.dataList)
}
},
}
}
</script>
Después modificamos los archivos del store con lo siguiente:
Modificamos el archivo state.js:
export default {
pokemons: [],
pokemonsWithSearchFilter: [],
}
Modificamos el archivo getters.js:
export default {
POKEMONS: state => {
return state.pokemons
},
POKEMONS_WITH_SEARCH_FILTER: state => {
return state.pokemonsWithSearchFilter
}
}
Modificamos el archivo mutations.js:
export default {
SET_POKEMONS(state, data) {
state.pokemons = data
},
SET_POKEMONS_WITH_SEARCH_FILTER(state, data) {
state.pokemonsWithSearchFilter = data
}
}
Modificamos el archivo actions.js:
export default {
getPokemonsData: async (context, payload) => {
try {
let { data } = await axios.get('/pokemons')
context.commit('SET_POKEMONS', data)
context.commit('SET_POKEMONS_WITH_SEARCH_FILTER', data)
} catch (e) {
console.log(e)
}
},
}
Una vez editado los archivos del “store”, tenemos que editar el componente PokedexComponent.vue para importar el componente “TheSearchBox” y agregarlo al grid de Tailwind:
<template>
<div>
<the-search-box></the-search-box>
<div class="grid grid-cols-3 gap-4">
<the-item-data v-for="item in items" :data-item="item" :key="item.code" />
</div>
</div>
</template>
<script>
import store from "../store/store"
import TheItemData from "./TheItemData";
import TheSearchBox from "./TheSearchBox";
export default {
name: "PokedexContent",
components: {
'the-item-data': TheItemData,
'the-search-box': TheSearchBox,
},
created() {
this.$store.dispatch('getPokemonsData')
},
store,
computed: {
items: {
get () {
return this.$store.getters.POKEMONS_WITH_SEARCH_FILTER
},
set (value) {
this.$store.commit('SET_POKEMONS_WITH_SEARCH_FILTER', value)
}
},
},
}
</script>
Con esta adaptación ya será posible buscar por nombre del Pokemon en nuestra lista de Pokemones
Conclusión de las series(PHP Puro y Laravel)
Adaptar un framework de cualquier lenguaje dependería del costo-beneficio del análisis del proyecto, hay ocasiones que los mismos frameworks no se adaptan a las necesidades de los proyectos y se tienen que crear herramientas mas personalizadas es aquí donde entra el lenguaje nativo o puro, pero si el framework es flexible se pueden crear estas mismas adaptadas al framework.
Aquí la ruta de aprendizaje vendría a impactar el costo beneficio del proyecto, ya que cuando que vayamos a usar un framework siempre debemos aprender antes el lenguaje nativo del framework, esto para tener una productividad mas optima a la hora de empezar a desarrollar con el framework.
Y como hemos visto en estas publicaciones un framework aumenta mucho la productividad; en las series de PHP simplemente tuvimos que crear todas las herramientas desde cero, a comparación de las series con Laravel que ya se tiene la integración de estas herramientas lo que aumenta mucho la productividad de un proyecto, aparte da un estándar de programación(aunque aun así todavía se puedan cometer errores garrafales) y semántica en el código.
No hay una regla que dicte el porque debas usar mejor el lenguaje nativo contra el framework o viceversa, es el simple análisis de costo beneficio, la curva de aprendizaje y el desempeño o herramientas que se van a desarrollar que a la mejor dicta que puedes usar en tu proyecto.
De aquí en adelante publicare features sobre el Pokedex en Laravel, para mejorar o incluir funcionalidad mas optima para el proyecto.
Si quieres revisar el código fuente del proyecto, lo puedes hacer aquí:
Si quieres revisar el código de las publicaciones de PHP, lo puedes hacer aqui:
Si quieres aprender sobre Vuex, lo puedes consultar aqui:
Si quieres leer de nuevo las publicaciones de PHP, aquí lo puedes hacer: