Vue3 has been released for some time. It adopts a new responsive system and builds a new Composition API. The surrounding ecology of Vue is stepping up the adaptation of this new system, and the official state management library Vuex is also being adapted. Therefore, the official puts forward a Vuex 5 A new proposal.
- Support two syntax to create Store: Options Api and Composition Api;
- Delete mutations. Only state, getters and actions are supported;
- Modular design, can well support code segmentation;
- There are no nested modules, only the concept of Store;
- Complete TypeScript support;
Below this proposal, there is an interesting comment. Simply translate:
Unfortunately, as like as two peas, unfortunately, Vuex5's proposal is not related to the functions of Pinia, but it can only be said to be the same. Today's article will introduce this pineapple to you.
install
In the existing project, the following commands have been used to install the Pinia module.
# yarn yarn add pinia@next # npm npm i pinia@next
After installation, you need to import and install in the entry file of Vue3 project.
// main.js import { createApp } from 'vue' import { createPinia } from 'pinia' import App from './App.vue' // Instantiate Vue const app = createApp(App) // Install Pinia app.use(createPinia()) // Mount in real DOM app.mount('#app')
Get started
To use Pinia, you only need to define a store and import it where the data is used.
Define Store
import { defineStore } from "pinia" // Expose a use method to the outside, which will export the state defined by us const useCounterStore = defineStore({ // The id of each store must be unique id: 'counter', // state indicates the data source state: () => ({ count: 0 }), // getters is similar to computed and can perform secondary calculation on the value of state getters: { double () { // this in getter points to 👉 state return this.count * 2 }, // If you use the arrow function, there will be a problem with this pointing // You can get state in the first parameter of the function double: (state) => { return state.count * 2 } }, // actions is used to modify the state actions: { increment() { // this in action points to 👉 state this.count++ }, } }) export default useCounterStore
In addition to using the vuex like method above to build a state, you can also use the form of function to create a store, which is somewhat similar to setup() in Vue3.
import { ref, computed } from "vue" import { defineStore } from "pinia" // Expose a use method to the outside, which will export the state defined by us const useCounterStore = defineStore('counter', function () { const count = ref(0) const double = computed(() => count.value * 2) function increment() { count.value++ } return { count, double, increment } }) export default useCounterStore
Use Store
As mentioned earlier, Pinia provides two ways to use store, Options Api and Composition Api, which are perfectly supported.
Options Api
In Options Api, you can directly use the mapActions and mapState methods provided by the government to export the state, getter and action in the store. Their usage is basically the same as that of Vuex and is easy to use.
import { mapActions, mapState } from 'pinia' import { useCounterStore } from '../model/counter' export default { name: 'HelloWorld', computed: { ...mapState(useCounterStore, ['count', 'double']) }, methods: { ...mapActions(useCounterStore, ['increment']) } }
Composition Api
In Composition Api, both state and getter need to monitor changes through the calculated method, which is the same as that in Options Api, which needs to be placed in the calculated object. In addition, the state value obtained in Options Api can be modified directly. Of course, it is recommended to write an action to operate the state value for later maintenance.
// Composition Api import { computed } from 'vue' import { useCounterStore } from '../stores/counter' export default { name: 'HelloWorld', setup() { const counter = useCounterStore() return { // Both state and getter need to use computed, which is the same as Options Api count: computed(() => counter.count), double: computed(() => counter.double), increment: () => { counter.count++ }, // You can directly modify the value of state increment: counter.increment, // You can reference the action s defined in the store } } }
Type prompt
In Vuex, TypeScript's type prompt is not very good, and its state can only be found during type derivation. Especially in the process of writing code, the code prompt is not intelligent.
pinia can deduce all defined state s, getter s and action s, which will be much more convenient when writing code.
pinia has a very friendly type definition through TypeScript. If you are interested, you can see pinia's type definition file (pinia.d.ts):
Code segmentation
Due to the use of modular design, all stores can be introduced separately, instead of mounting all modules to one store through modules like vuex.
Suppose we create a Store through Vuex. There are two modules under the Store, namely, User module and Goods module. Even if only User information is used on the current home page, the whole Store will be packaged into js chunk on the home page.
If we use pinia, we will use defineStore to define two completely separate stores. When the two pages are introduced, they will not affect each other. Finally, when packaging, the js chunk on the home page and the js chunk on the product page will package the corresponding store respectively.
The introduction of Pinia has come to an end here. If there are new projects to be developed using Vue3, it is recommended to use Pinia without brain, which is more concise and only 1KB in size.