Espera un momento 🎁 ...
¿Te gustaría aprender a programar, gratis?
Sólo debes registrarte 😉.
Regístrate o inicia sesión para continuar aprendiendo:
Procedamos a definir un nuevo store para nuestros productos. Así mismo, veamos cómo filtrar productos por categoría, haciendo uso de un getter.
Vamos a crear un nuevo archivo llamado product.ts
.
Importaremos el método defineStore
de pinia
y definiremos un estado, unos getters y unas acciones.
El nombre de nuestro store será Products
, y exportaremos useProductsStore
.
La idea es desplazar la información de los productos desde ProductList
hacia el nuevo store, que se encargará de gestionar y filtrar los productos.
El state
que teníamos dentro de ProductList
lo moveremos al state
del nuevo store.
Así, ProductList
ya no tendrá un state
, sino una computed property para acceder a los productos desde el store.
mapState
Podemos aprovechar la función mapState
, que ya hemos visto en lecciones anteriores.
Indicamos el store que queremos usar, en este caso useProductStore
, y dentro de un arreglo especificamos el estado que nos interesa (products
).
Guardamos para poder usar el store, importando useProductStore
desde stores/products
y mapState
desde pinia
.
De esta manera, importamos useProductStore
desde el archivo correspondiente y mapState
desde pinia
para mapear una computed property en nuestro componente, asociada al estado products
.
Nuestro componente sigue funcionando y muestra un product cart
por cada producto, pero ahora los productos se leen desde el store de products
.
El objetivo es definir un getter que devuelva productos filtrados por categoría.
La información original de los productos se mantendrá intacta, pero el getter devolverá una lista filtrada.
Utilizamos returnState.products.filter
para aplicar un filtro que devuelva solo productos cuyo categoryId
sea 1
.
Como ProductList
accede al getter de products
, ya no devolveremos la lista completa de productos, sino solo la filtrada.
Al actualizar, verificamos que solo aparecen tres productos porque estamos filtrando por la categoría 1
.
Podemos agregar un stateCategoryId
que inicialmente sea null
, y al navegar a una ruta, el categoryId
cambiará.
Si categoryId
es null
, devolvemos todos los productos.
Si categoryId
tiene un valor, aplicamos un filtro para devolver solo los productos con el categoryId
especificado.
selectCategory
Definimos una acción llamada selectCategory
, que recibe un categoryId
y actualiza el estado:
this.categoryId = categoryId;
Aquí nos puede saltar un error, ya que categoryId
es inicialmente null
, pero queremos que acepte tanto number
como null
.
Para solucionar esto, definimos categoryId
como tipo number | null
.
Guardamos los cambios y verificamos que ProductList
no se ve afectado. Sigue pidiendo los productos, y el getter se encarga de devolver lo correspondiente.
Para finalizar, llamamos la acción selectCategory
para actualizar la categoría según sea necesario.
Esta lección no cuenta con recursos adicionales.
Si crees que hace falta algo, o necesitas ayuda, puedes publicar una pregunta en el foro.
Entonces vamos a crear un nuevo archivo y lo vamos a llamar "product.ts". Aquí vamos a importar el método "defineStore" que nos proporciona "pinia" y en su interior vamos a definir un estado, unos "getter" y unas acciones. El nombre de nuestro "store" será “Products” y vamos a hacer export de “useProductsStore”, la idea es desplazar la información de los productos desde "ProductList" hacia nuestro nuevo "store", porque este "store" se va a encargar de gestionar la información de los productos de sí mismo, de filtrarlos. Entonces este "state" que teníamos dentro de productos lo vamos a llevar ahora al “state” de nuestro nuevo "store". Entonces ahora "ProductList" no va a tener un "state", pero sí que va a tener una “computed property” para acceder a los productos desde el "store" correspondiente. Aquí podemos aprovechar la función "mapState", que ya hemos visto en lecciones anteriores. Simplemente indicamos aquí qué "store" queremos usar. En este caso "useProductStore" y dentro de un arreglo indicamos cuál es el estado que nos interesa. En este caso “products”. Guardamos para poder usar el "store". Vamos a importar “useProductSstore" desde “stores/products” y siguiendo la misma idea, vamos a importar "mapState" desde "pinia". Entonces, de esta manera, nosotros vamos a importar “useProductStore" desde el archivo correspondiente y vamos a importar "mapState" desde "pinia". De tal manera que podamos mapear una “computer property” en nuestro componente actual asociado a el estado ”products” que nos ofrece el "store" de productos. Luego que estamos accediendo a los productos de esta manera nuestro componente seguirá funcionando y ello lo podemos verificar aquí en el navegador. Se sigue mostrando un “product cart” por cada producto, la única diferencia es que los productos están leyendo desde el "store" de “products”. Bien, por aquí hicimos todo esto. Bueno, la idea de esto es que podamos luego definir un "getter" y si hay un filtro, por ejemplo, por categoría, el “getter” solo devuelva lo que corresponde, por ejemplo, a nuestra data de productos, le vamos a poner un “_”, de tal manera que la información original de los productos se mantenga intacta. Pero cuando se pida a través del "getter" la lista de productos esta lista, modifique esta data y devuelva lo que corresponda. Por ejemplo, vamos a devolver los productos filtrados por categoría, vamos a hacer aquí "return". Recordemos que los “getters” tienen acceso al "state", entonces vamos a hacer “returnState.products.filter” y vamos a aplicar aquí un filtro. Queremos que solo se devuelvan un producto cuyo “categoryId” sea igual a “1”. Por ejemplo, si hacemos ello como "ProductList" está accediendo al "getter" de “products”, ya no vamos a devolver la lista completa de productos. Esto más bien va a ser tratado como un estado interno y lo que vamos a estar devolviendo es el resultado del "getter", que es la lista de productos filtrada por categoría. Entonces actualizamos y nos encontramos con esto. Tenemos solo tres productos. ¿Por qué? Porque estamos filtrando por categoría en este caso, estamos sólo devolviendo productos que pertenecen a la categoría uno. ¿De qué manera hacemos que esto funcione de manera dinámica? Bueno, así como tenemos un “state products”, podemos tener un “stateCategoryId” de tal manera que este “categoryId” en un inicio sea “null”. Pero luego de que se navega a una ruta el “categoryId” cambie de tal manera que aquí vamos a poder usar una condición. De tal manera que, si no hay un “categoryId”, vamos a devolver simplemente los productos tal cual los tenemos guardados. Pero en caso de que si hubiese un “categoryId” vamos a devolver los productos pero con un filtro. Vamos a devolver aquellos cuyo “categoryId” es igual al que se ha especificado acá y luego tenemos que permitir al usuario actualizar el estado. Para esto vamos a definir un “action” que se va a llamar “selectCategory”. Este action “selectCategory” va a recibir un “categoryId” que es un número y simplemente se va a encargar de actualizar el estado. Aquí ponemos “this.categoryId = categoryId” que se está recibiendo como valor. Aquí nos está saltando un error. Porque nos dice que estamos tratando de asignar un “number” a un valor nulo. La idea es que el “categoryId” acepte números, pero a la vez acepte valores nulos. ¿Cómo podemos declarar ello? Pues vamos a empezar con el valor de null, pero vamos a decir que el tipo en realidad es “number” o “null”. “categoryId” va a aceptar tanto “number” como “null”. Muy bien, entonces hasta aquí guardamos y listo. El “ProductList” no se entera de ello, no se entera de nada, simplemente sigue pidiendo a los productos y el "getter" se encargará de devolver lo que corresponde. Lo único que nos falta es usar este nuevo “action”. Este “action”, tenemos que llamarlo para cambiar la categoría.
¿Tienes dudas?
Publicar preguntaRegístrate
Inicia sesión para llevar un control de tu progreso.
Capítulos
Estás viendo un capítulo de la serie Aprende Vue 3, Vite, VueRouter, Vuetify, Pinia y TypeScript
Espera un momento 🎁 ...
¿Te gustaría aprender a programar, gratis?
Sólo debes registrarte 😉.