تماشای این درس نیاز به اشتراک حرفه‌ای دارد.

Introducing Pinia Store0:05

So far we've been managing our state in view using props. We then migrated to provide and inject. And finally we built our own composable for state management. While these approaches were great for smaller projects that can become a bit difficult to manage as your application and maybe even your team grows, this is where Pia comes in. Pia brands itself as the intuitive store for Vue.js and is maintained by the Vue core team.

Installing and Initializing0:26

Pia Brands itself as the intuitive store for VJS and is maintained by the View core team. Let's take a look at how useful Pina can be for us in our project. We first need to add Pina and we can do so as follows at Pina, then we can open up Main.js and let's initialize Pina. We can do so as follows, we will first import createPina from Pina. Then we'll create our store pia equals createPina.

Creating Cart Store0:48

we will first import CreatePina from Pina. Then we'll create or store pia equals CreatePina. And finally in our CreateApp we will use Pina as follow-ups. Now that pia has been added to our product, let's see how we can migrate our cart composable to Pina. In Pina we have this concept called stores kind of like our cart composable. So let's create a card store in our store directory and let's call it cartDo.js.

So let's create a card store in our store directory and let's call it cart.js. Much like our previous card composable. A PIA store holds state and business logic that isn't bound to your component tree. In our card.js file, we need to define the store using the findStore that's first imported. Next up, we need to initialize our store and we can do so as follows.

Next up, we need to initialize or store and we can do so as follows. We'll say const cartStore equals defineStore. We'll give it the name cart and let's initialize it with an empty object for now. And this constant will be exported. You can name the store anything you want, but the usual convention is to have the name of your file in this case cart surrounded by use and store. So we end up getting useCartStore.

of your file in this case cart surrounded by use and store. So we end up getting use cart store. Do note that the ID we gave earlier has to be unique across your entire application. The second argument is flexible and allows for two possible values. We can either use an object with a state or getters and/or actions. This is called an option store

and or actions. This is called an option store because it's very similar to Views Option API. The second value we can use is a setup store, which is similar to views Composition, API or refs become state computed. Properties become gatherers and functions become actions. And finally you return your state properties as follows.

and functions become actions. And finally you return your state properties as follows. You'll return our cart or totalPrice and our incrementProduct. You may recognize this syntax as this is basically our composable from our previous lesson. So for the sake of this lesson, let's go with a setupStore. Stores offer more flexibility.

with a setup store set up. Stores offer more flexibility but they come with the expense of being a bit more complex to work with. And as a matter of fact, let's get started with a refactor. They should be very easy. Let's open up our cart composable. Let's start by copying our return value and paste it in our setup store. Next up, let's copy all our other values. Go back to our PIA store.

Migrating Components to Store3:20

Next up, let's copy all our other values. Go back to our PIAStore and this time we can paste it inside of the defined store setup function. Next, we need to refactor our app a bit. So let's start with the ProductCard first. Let's import our PinaStore. We'll say import useCardStore from source/card.js. Next we have to initialize our store as follows.

source card js. Next we have to initialize or store as follows. So we'll say cardStore equals useCardStore. The return value of useCardStore is automatically made reactive. So unfortunately we cannot use Object destructuring anymore. So let's get rid of our composable. And now we have to make some modifications. We'll start by replacing cart.value with cardStore.cart

We'll start by replacing cart.value with cardStore.cart and we'll replace incrementProduct with cardStore.incrementProduct. I will do the same for decrementProduct. And if we test our page, everything should still work, except our product card component is now connected to Pia. While our other components are still connected to our composable, this means that we won't see the nav bar update when we add a product.

to our composable, this means that we won't see the nav bar update when we add a product to the cart, nor will we see the product being added to the cart. Let's fix that. Now, open up our nfr. We'll get rid of our composable, we'll say import { useCartStore } from './store/cart.js'. We'll initialize our store. We'll replace cart.value with cartStore. And now we'll see our nav bar update when we

We'll replace cart.value with cartStore. And now we'll see our nav bar update when we add something to the cart. Finally, let's also make sure our cart and our cartOverlay are migrated to our PIA store. Let's start with cart. So open up Cart.vue, remove or composable. By now you should know the drill. Import useCartStore from our stores/cart.js file will say const cartStore.

Import a useCardStore from our stores/cart.js file will say const cardStore equals useCardStore. And we'll replace removeProduct, incrementProduct and decrementProduct with cardStore.removeProduct, cardStore.incrementProduct and cardStore.decrementProduct. And finally, let's also replace cart with cardStore.cart. Open up cartOverlay.

with cardStore.cart. Open up cart overlay. Let's get rid of our Imposable import use cardStore from 'store/cart'. const cardStore equals use cardStore. And in our component, let's replace the subtotal with cardStore.subtotal. And if all went well, everything should be connected. Again, this is looking great. There's one more page left for us to do.

Again, this is looking great. There's one more page left for us to do and that's the checkout view. Let's get rid of our composable, let's import our store, let's and finally let's update our component. We'll say cardStore, clear card down here and our subtotal or taxes and our total should come from the store.

or subtotal or Texas and or total should come from the store. So we'll say cardStore, subtotal, cardStore, Texas and cardStore total. And now our entire application works again, end to end using pinia. This is great. Even persisting the state to our localStorage still works. At this point you may think, why did we go through this entire hassle

Using Pinia Devtools6:48

At this point you may think, why did we go through this entire hassle as our composable was basically identical to the Pina store? Well one of the most powerful features of Pina is the dev tools integration. If you open up the dev tools at the bottom of the page, you click on the little pineapple icon, you'll see the entire state of your entire application. If you click on our card store, we add something to the cart, we'll see it update in real time.

If you click on our card store, we add something to the cart, we'll see it update in real time. We can even dive in, modify the quantity and we'll see it change in our page. Now this is pretty powerful where we add our burger to the page. We'll see our cart update, but we notice our subtotal has a floating point rounding error. So let's fix that. Let's open our card store.

point rounding error. So let's fix that. Let's open our CardStore. And as a matter of fact, we can actually get rid of our composable so we won't get confused. Let's open up our CardStore from Pinya. Let's find the subtotal function. And here we'll say $subtotal equals our function. And we'll return math around $subtotal times 100 divided by 100. And now we'll see our $subtotal is rounded beautifully.

subtotal times 100 divided by 100. And now we'll see our subtotal is rounded beautifully. Alright, so let's say we have a pretty elaborate state. For example, we have five burgers, we have five salads and we have five pizzas. Alright, so now the batch reflects that we have 15 items, but our designer came back and said like, Hey, whenever we exceed 10 items, we actually want to display nine plus in the batch. Alright, let's do that. Let's open up our nav bar.

to display nine plus in the batch. Alright, let's do that. Let's open up our nav bar. We'll say amount is lesser than 10. If so, let's display the amount and otherwise we'll say nine plus. We go back and we see an update and this looks great, but let's assume someone else from our team wants to test this and this requires them adding 10 items to the cart, which is actually a bit of a burden. Lucky for us. We can go in the dev tools, we can open a pin

to the cart, which is actually a bit of a burden. Lucky for us. We can go in the dev tools, we can open a pin and we can export the current state by pressing this icon. So we can say serialize and copy the state. And if we have an empty state like here, we can go back to the dev tools, we can press paste. I will see our previous state we copied being restored. Now this is very powerful stuff because you can also save the state as a JSON file. You can even check it into your project, share it.

because you can also save the state as a JSON file. You can even check it into your project, share it with your entire team, and then they can load the state from set JSON file. I find myself using this all the time. Now the timeline feature, in my opinion, is a bit hard to navigate in its current form, but it can be useful to see what mutations are triggered. To see this in action, open the timeline tab and press the record icon.

To see this in action, open the timeline tab and press the record icon. Whenever we mutate a state, it'll be recorded inside the timeline and we can open up the event and we can see that the action incrementProduct was triggered on our cart with the following argument burger. If you open up the mutation, you can see the quantity has been changed from five to six, which is reflected in our ui. Now notice how the events

which is reflected in our ui. Now notice how the events and the mutations are logged multiple times. This is because of how the current version of the tools interact with Penia. So currently there's a lot of noise to filter through, so I find myself not using the timeline view as often as I would like before. Moving on to the next lesson, let's reflect a bit on what we did.

Lesson Wrap-Up10:00

Moving on to the next lesson, let's reflect a bit on what we did. We added Penia to our project and we created our first card store, which we used throughout our application instead of our composable, we used the setup store variant instead of the option store because it made refactoring easy and it's more flexible. But remember with great flexibility, the trade off usually is some complexity.

But remember with great flexibility, the trade off usually is some complexity. Finally, we played around with the view dev tools and more specifically the pin tab. And here we were able to peek inside our state, do modifications and save load specific states. Very powerful stuff. Alright, now let's move on to the next lesson. I'll see you there.

I'll see you there.

دوست دارید گاهی خبرهای Laracasts را ایمیل کنیم؟