Make writing a habit together! This is the third day of my participation in the “Gold Digging Day New Plan · April More text Challenge”. Click here for more details.


In the proposal of VEX5, the following ideas are stated:

  • Supports both the Options API and composition API syntax for creating stores
  • Mutations are not necessary, but state, getters and actions are enough
  • There are no nested modules, but composite stores instead
  • Support for TS
  • Good support for code segmentation

Pinia was also originally intended to explore what the next generation of Vuex might look like, incorporating many of the ideas discussed by the Vuex 5 core team. Eventually, they realized that Pinia already implemented most of what they wanted in Vuex 5, so they used it as a next-generation state manager.

Compared to Vuex, Pinia’s API is cleaner, more in line with everyday development habits, and more importantly, has more robust type inference when used with TypeScript.

Here is an online Pinia Demo provided by the official Pinia website, you can learn from it.

Installation and use

Install Pinia in your project using YARN or NPM

yarn add pinia
// or with npm
npm install pinia
Copy the code

In main.js, create a Pinia and mount it to your app

// vue3
import { createPinia } from 'pinia'
import { createApp } from 'vue'
import App from './App.vue'

createApp(App).use(createPinia()).mount('#app')


// vue2
import { createPinia, PiniaVuePlugin } from 'pinia'

Vue.use(PiniaVuePlugin)
const pinia = createPinia()

new Vue({
  el: '#app',
  // ...
  pinia,
})
Copy the code

Store

When we define a store, we need to pass it a unique name, which acts as an ID and cannot be repeated with other stores.

In terms of store naming, we can agree on usexxx, such as useStore, which is more consistent with our development naming conventions.

Within a component, you simply instantiate a store and use its internal state, actions, and getters directly.

// @/store/counter import { defineStore } from 'pinia' export const useCounterStore = defineStore('counter', { state: () => { return { counter: 0, name: 'Eduardo', item: [],}}, }) import {useStore} from '@/stores/counter' export default {setup() {const store = useStore() return { store, } }, }Copy the code

One thing to note here is that you can’t directly deconstruct the values in the store, otherwise you lose responsiveness. We can solve this problem with storeToRefs.

const store = useStore()
const { name, counter } = storeToRefs(store)
Copy the code

State

There are four ways to modify State

We can directly change the value in State without using mutations like VUex, which is applicable to the change of a single attribute value.

const store = useStore()
store.counter++
Copy the code

You can also use $patch to change multiple property values in state

store.$patch({
  counter: store.counter + 1,
  name: 'Abalam',
})
Copy the code

In the above case, the parameter passed to $patch is an object, and another method is the transfer function, which is more suitable for manipulating some complex properties such as arrays and objects.

store.$patch((state) => {
  state.items.push({ name: 'shoes', quantity: 1 })
  state.counter++
})
Copy the code

We can even change the state by replacing the entire state

store.$state = { counter: 666, name: 'Paimon' }
Copy the code

Reset the state

If you want to reset a property in state to its original value, instead of assigning it individually, Pinia provides a $reset method to help you reset it with one click.

const store = useStore()

store.$reset()
Copy the code

Getters

Getters can evaluate properties by analogy, or use this to directly access other gettters in the store.

Similarly, getters also has caching features. Even if the same getters is called many times, as long as the value remains unchanged, it will only be executed once.

export const useStore = defineStore('counter', {
  state: () => ({
    counter: 0,
  }),
  getters: {
    doubleCount: (state) => state.counter * 2,
    doubleCountPlusOne() {
      return this.doubleCount + 1
    },
  },
})
Copy the code
 const store = useStore()
 store.doubleCount
Copy the code

Action

In Pinia, actions can be both synchronous and asynchronous, which is also more useful than Vuex.

export const useUsers = defineStore('users', {
  state: () => ({
    userData: null,
  }),

  actions: {
    async registerUser(login, password) {
      try {
        this.userData = await api.post({ login, password })
      } catch (error) {
        return error
      }
    },
  },
})
Copy the code
const user = useUsers()
user.registerUser('123','123')
Copy the code

conclusion

These are some of the ways Pinia is used. Pinia has become the default state management tool, and it will be much better than Vuex in terms of experience. We will use Pinia more and more in the future, so learn it first.

If there is anything wrong in this article, I will also forget to correct you.