The foreword 0.

Pinia is a proposal to test the next iteration of Vuex

The proposal for VEX5 is a big improvement over vex3 and 4

  • supportoptions api and composition api
  • There is nomutations
  • There are no nested modules
  • bettertypescriptsupport
  • Automated code splitting

1. Comparison with Vuex

Pinia tries to be as close to Vuex as possible. It was designed to test the proposal for the next iteration of Vuex and has been successful, with an open RFC for Vuex 5 that is very similar to the API used by Pinia. Please note that Pinia author I (Eduardo) is a member of the vue.js core team and is actively involved in the design of apis such as Router and Vuex. The intention for this project was to redesign the experience of using the Global Store while maintaining Vue’s approachable philosophy. Make Pania’s API as close to Vuex’s as it moves forward and can easily migrate to Vuex or even merge the two projects in the future.

The Pinia API is very different from Vuex ≤4:

  • There is nomutations. Mutations are considered very lengthy. Devtools integration was initially brought in, but this is no longer an issue.
  • There is no more nested structure of modules. You can still implicitly nest stores by importing and using stores in another store, but Pinia provides a flat structure by design while still supporting cross-store composition. You can even have cyclic store dependencies.
  • bettertypescriptSupport. There’s no need to create complex custom wrappers to support TypeScript, everything is typed, and the API is designed to take advantage of TS type inference as much as possible.
  • No more need to inject, import functions, call them, and enjoy autocomplete!
  • There is no need to add stores dynamically; by default they are all dynamic and you won’t even notice. Note that you can still register it manually with store at any time, but because it’s automatic, you don’t have to worry.
  • No namespace module. Given the flat architecture of the store, the “namespace” store is inherent in the way it is defined, and you could say that all stores are namespace.

2. Pinia advantages

2.1 intuitive

Stores are as familiar as components. Apis are designed to let you write well-organized stores.

2.2 Type Safety

Types are inferred, which means that stores give you auto-complete functionality even in JavaScript

2.3 Developer tool support

Pinia hooks up with Vue DevTools to provide enhanced Vue 2 and Vue 3 development experiences.

2.4 extensible

Respond to storage changes to extend Pinia through transactions, local storage synchronization, and so on.

2.5 Modular Design

Build multiple stores and have the packaging code automatically split them.

2.6 light

Pinia is about 1KB in size

3. Basic use

// stores/counter.js
import { defineStore } from 'pinia'

export const useCounterStore = defineStore('counter', {
  state: () = > {
    return { count: 0}},// could also be defined as
  // state: () => ({ count: 0 })
  actions: {
    increment() {
      this.count++
    },
  },
})
Copy the code

Use it in components:

import { useCounterStore } from '@/stores/counter'

export default {
  setup() {
    const counter = useCounterStore()

    counter.count++
    / / with autocompletion ✨
    counter.$patch({ count: counter.count + 1 })
    // or using an action instead
    counter.increment()
  },
}
Copy the code

You can even define stores for more advanced use cases using functions (like component setup()) :

export const useCounterStore = defineStore('counter', () => {
  const count = ref(0)
  function increment() {
    count.value++
  }

  return { count, increment }
})
Copy the code

If you’re not familiar with the Setup ()Composition API, Pania also supports Map Helpers like Vuex. You define stores in the same way, using mapStores(), mapState(), or mapActions() :

const useCounterStore = defineStore('counter', {
  state: () = > ({ count: 0 }),
  getters: {
    double: (state) = > state.count * 2,},actions: {
    increment() {
      this.count++
    }
  }
})

const useUserStore = defineStore('user', {
  // ...
})

export default {
  computed: {
    // other computed properties
    // ...
    // gives access to this.counterStore and this.userStore. mapStores(useCounterStore, useUserStore)// gives read access to this.count and this.double. mapState(useCounterStore, ['count'.'double']),},methods: {
    // gives access to this.increment(). mapActions(useCounterStore, ['increment']),}},Copy the code

Pinia website link