Why Pinia?

Vuex 4’s support for typescript was disappointing, so state management abandoned Vuex in favor of Pinia. Here are five key criteria for adopting Pinia:

  • PiniaAPI design is very closeVuex 5 的The proposal. (The writer is a member of Vue core team)
  • Don’t need to likeVuex 4Customizing complex types to support typescript is inherently perfect for type inference.
  • Modular design, every store you introduce can be split automatically when packaged.
  • There is no nesting structure, but you can cross and combine them between any store.
  • Pinia is linked to Vue DevTools and will not affect the Vue 3 development experience.

Here is a brief introduction to how to use Pinia and compare the differences and precautions of VUEX. Please refer to the official documentation for details.

Store

Before delving into the core concepts, we need to know what stores are built into scaffolding and how to customize them.

Built-in Store

Store instructions API
useUserStore User login and information management details
useMenuStore Routing & Menu management details
useLogStore Log management details

Create the Store

Pinia is already built into scaffolding and associated with vue, so you can create a store anywhere:

import { defineStore } from 'pinia'

export const useUserStore = defineStore({
  id: 'user'.state: () = >({}),
  getters: {},
  actions: {}})Copy the code

This is very different from Vuex in that it is a standard Javascript module export, which also makes it clear to developers and your IDE where the Store is coming from.

Difference between Pinia and Vuex

  • The ID is required to connect the store being used to DevTools.
  • Creation method:new Vuex.Store(...)(vuex3),createStore(...)(vuex4).
  • In contrast to Vex3, state is now a function return object.
  • There is no mutations, don’t worry, the change of state is still recorded in DevTools.

State

Add attributes

Now that we’ve created the store, we can create some properties in state,

state: () = > ({ name: 'codexu'.age: 18 })
Copy the code

Setting the state property in the store to a function that returns an object with different state values is very similar to how we define data in components.

Use store in the template

Now we want to get the state of name from store, we just need to use the following method:

<h1>{{userStore.name}}</h1>

const userStore = useUserStore()
return { userStore }
Copy the code

Note that userstore.state.name is not required here.

While the above is comfortable, you must not deconstruct it to extract its internal values, as doing so will lose its responsiveness:

const { name, email } = useUserStore()
Copy the code

Getters

The getters in Pinia have the same functionality as getters in Vuex and computed properties in components. Traditional function declarations use this instead of passing state, but arrow functions still use the first argument of the function to get state. Because the arrow function handles the scope of this:

getters: {
  nameLength() {
    return this.name.length
  },
  nameLength: state= > state.name.length,
  nameLength: () = > this.name.length ❌ 
}
Copy the code

Actions

Unlike Vuex, Pinia only provides a way to define how to change the rules of the state, abandoning mutations and relying solely on Actions, which is a major change.

Pinia makes Actions more flexible

  • It can be called from a component or other action
  • Can be called from an action in another store
  • Called directly on the store instance
  • Support synchronous or asynchronous
  • There are any number of parameters
  • Can include logic on how to change the state (which is what Vuex’s mutations do)
  • can$patchMethod directly changes the status properties
actions: {
  async insertPost(data){
    await doAjaxRequest(data);
    this.name = '... '; }}Copy the code

Devtools

Scaffolding has the following code built in, which adds DevTools support:

import { createPinia, PiniaPlugin } from 'pinia'

Vue.use(PiniaPlugin)
const pinia = createPinia()
Copy the code

In Vue 3, some features such as time travel and editing are still not supported because vue-DevTools does not yet expose the necessary apis.