Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Karleb
Karleb

Posted on

     

First Look At Pinia: A VueJS State Management System

Pinia is one of the newest projects from the Vue ecosystem and it is the new official state management tool for Vue.js apps. Its API is similar to Vuex (its predecessor) and it is designed to be faster and more lightweight. According toPinia's Official Website, Pinia was born out of the experiment to redesign what a Store for Vue could look like with the Composition API. It is an upgrade on Vuex and compatible with Vue 2 and options API.

Note: This tutorial uses<script setup>, composition API and Vue 3.

Installation

  • Run the following code in your terminal to create a new Vue project.

  • Input the project name in the command prompt.

  • Select Vue.

  • Select yes when the command prompt asks to add Pinia to state management system.

npmcreatevite@latest
Enter fullscreen modeExit fullscreen mode

Pinia can be installed in an existing application with npm. Run the following command in your terminal to install Pinia in an existing application.

npminstallpinia//oryarnaddpinia
Enter fullscreen modeExit fullscreen mode

Project Configuration

The application has to know to use Pinia, so we tell it to use it in themain.js file.

import{createApp}from'vue'import{createPinia}from'pinia'importAppfrom'./App.vue'import'./style.css'constpinia=createPinia()constapp=createApp(App)app.use(pinia)app.mount('#app')
Enter fullscreen modeExit fullscreen mode

We importedcreatePinia fromPinia, instantiated it and instructed the application to use it by simply adding it to the Vue application's instance.

Pinia Store Setup

Create astores folder in thesrc folder. In the newly createdstores folder, create aproducts.js file.

The store file isprojects.js in our case here

Next, we need to importdefineStore in theproducts.js file and use it.

import{defineStore}from"pinia"constuseProductsStore=defineStore("products",{state:()=>({products:[description:"Your perfect pack for everyday use and walks in the forest. Stash your laptop (up to 15 inches) in the padded sleeve, your everyday",category:"men's clothing",image:"https://fakestoreapi.com/img/81fPKd-2AYL._AC_SL1500_.jpg",rating:{rate:3.9,count:120},]}),getters:{},actions:{},})
Enter fullscreen modeExit fullscreen mode

We use thedefineStore() method by:

  • Assigning it to a variable. Even though you can name the variable anything, the convention is to start the nameuse, then the name of the store file in singular and end it withstore. In this case, the variable name isuseProducutStore

  • ThedefineStore() takes an optional name which is the name of the store and an options object. This serves as an id for the store.

  • The options object houses thestate,setters andactions objects and I have added aproducts array that contains a single product.

Unlike in Vuex, Pinia does not have amutations object, theactions are where mutation of state and asynchronous request happens.

The options object is very similar to the options API. The setters are like the computed properties and actions, like methods.

I love this because not being able to put state mutation and methods that make API calls in one object has been a pain. It has led to having methods with similar names both in mutations and actions, the one in actions makes the API call while the one in mutations adds the fetched data into the state.

We are going to add a couple of states and methods to the options object.

import{defineStore}from"pinia"exportconstuseProductsStore=defineStore("products",{state:()=>({counter:0,categories:[],products:[{id:1,title:"Fjallraven - Foldsack No. 1 Backpack, Fits 15 Laptops",price:109.95,description:"Your perfect pack for everyday use and walks in the forest. Stash your laptop (up to 15 inches) in the padded sleeve, your everyday",category:"men's clothing",image:"https://fakestoreapi.com/img/81fPKd-2AYL._AC_SL1500_.jpg",rating:{rate:3.9,count:120},},],}),getters:{getCounter:state=>state.counter,getAllProducts:state=>state.products.length,},actions:{incrementCounter(){this.counter++},addProduct(product){if(!product.length)returnthis.products.push(product)},asyncgetCategories(){awaitfetch("https://fakestoreapi.com/products/categories").then(res=>res.json()).then(data=>{this.categories.push(data)})},},})
Enter fullscreen modeExit fullscreen mode

In the code above, I have added:

  • categories state to store the categories.

  • counter state to count arbitrary numbers.

  • getCounter() getter to get the currentcounter's count.

  • getAllProducts() getter all products.

  • incrementCounter() action to increment the counter.

  • addProduct() action to add a product.

  • getCategories() action to make an asynchronous call to an endpoint that gets all categories and populate them to state.

In theactions object, the state is not passed into the functions, rather, they are accessed throughthis keyword.this return the current store instance. This implies that allactions functions must be regular functions and not arrow functions.

import{defineStore}from"pinia"exportconstuseProductsStore=defineStore("products",{...getters:{getCounter(){this.counter},getAllProducts(){this.products.length},},...})
Enter fullscreen modeExit fullscreen mode

In the getters objects, the state can be substituted withthis keyword, which returns the store instance. Meaning, the arrow functions have to be changed to regular functions.

How to access Pinia getters in another getter

Getters can be accessed and used in another getter usingthis keyword.

getters:{...getAllProducts(){returnthis.products.length},doubleProductsSize(){returnthis.getAllProducts*2},},
Enter fullscreen modeExit fullscreen mode

We doubled the size of all the products that were returned bygetAllProducts() getter in the newdoubleProductsSize() getter.

How to access Pinia actions in another getter

Actions can be accessed and used in another action usingthis keyword.

actions:{incrementCounter(){this.counter=this.counter+1},...asyncgetCategories(){this.incrementCounter()awaitfetch("https://fakestoreapi.com/products/categories").then(res=>res.json()).then(data=>{this.categories.push(data)})},},
Enter fullscreen modeExit fullscreen mode

We incremented the counter each time we get all products categories by callingincrementCounter() action in thegetCategories() async action.

How to access Pinia state in Vue components

In the components, Pinia states are accessed by importing the store in the component and passing it into astoreToRefs() method provided by Pinia where they can be destructured before they are used.storeToRefs() helps to extract the state while keeping its reactivity.

import{useProductsStore}from"./stores/products"import{storeToRefs}from"pinia"conststore=useProductsStore()const{categories,counter,products}=storeToRefs(store)
Enter fullscreen modeExit fullscreen mode

How to access Pinia getters in Vue components

Getters can be accessed on the object instance.

import{useProductsStore}from"./stores/products"conststore=useProductsStore(){{store.getCounter}}{{store.getAllProducts}}
Enter fullscreen modeExit fullscreen mode

They can also be destructured by passing the store object instance through thestoreToRefs() method.

import{useProductsStore}from"./stores/products"conststore=useProductsStore()const{getCounter,getAllProducts}=storeToRefs(store)
Enter fullscreen modeExit fullscreen mode

How to access Pinia actions in Vue components

Action methods can be destructured off the store object instance.

import{useProductsStore}from"./stores/products"conststore=useProductsStore()const{getCategories}=storeonBeforeMount(()=>getCategories())
Enter fullscreen modeExit fullscreen mode

They can be accessed on the store object instance directly.

import{useProductsStore}from"./stores/products"conststore=useProductsStore()onBeforeMount(()=>store.getCategories())
Enter fullscreen modeExit fullscreen mode

Conclusion

Pinia is a state management library for Vue.js that provides a way to manage and share reactive states across components in a Vue.js application.

In this tutorial, we learned how to create a Pinia store using thedefineStore() function and use it in a Vue.js component. We saw how to define state properties, getters and actions functions that can mutate the state and perform asynchronous calls in the store, and how to access them in a component using theuseStore() andstoreToRefs() functions provided by Pinia.

Pinia provides a powerful and flexible way to manage states in Vue.js applications, and it's well-suited to large and complex applications where state management can become a challenge. Its use of the Composition API makes it easy to use and understand, and its integration with Vue.js 3 means that it works seamlessly with other Vue.js features and libraries.

Overall, Pinia is a great choice for developers looking for a modern and flexible state management library for their Vue.js applications. It provides a solid foundation for building complex and scalable applications, and its simple and intuitive API makes it easy to learn and use.

Top comments(0)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

I love to make things work.
  • Joined

Trending onDEV CommunityHot

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp