Article Directory
- foreword
- 1. What is pinia?
- 2. Why use Pinia?
- 3. Pinia vs. Vuex
- 4. Specific usage method
- Five , state
- Six , getters
- 1. Access getters
- 2. Getters pass parameters
- 3. Write as a normal function to call this
- 4. Access getters in other stores
- Seven , actions
- 1. Access actions
- 2. Call actions in other stores
- 8. Easter eggs —— shopping cart case sharing
- Summarize
foreword
Friends who have studied Vue2 must have used Vuex. We know that Vuex is a plug-in for centralized management status in Vue. So what is used to manage status in Vue3? How to use it? This article will elaborate on this issue.
At the end of this article, I will share a simple shopping cart case implemented using Vue3+Pinia. , interested friends can try to complete it, I believe it will greatly improve your mastery of Vue3 and pinia! ! !
1. What is Pinia?
Pinia was originally redesigned around November 2019 to use the Composition API . Since then, the original principles remain the same, but Pinia works for both Vue 2 and Vue 3, and doesn't require you to use the composition API.
2. Why use Pinia?
Pinia is a repository for Vue that allows you to share state across components/pages. If you're familiar with the Composition API, you might think that you can already pass a simple
export const state = reactive({})
. But even in small single-page applications, you can get a lot of benefits from using Pinia:
- dev-tools support
- Timeline to track actions, mutations
- Stores appear in the components that use them
- time travel and easier debugging
- Hot Module Replacement
- Modify your Store without reloading the page
- Keep any existing state while developing
- Plugins: Extend Pinia functionality with plugins
- Proper TypeScript support or autocompletion for JS users
- Server-Side Rendering Support
3. Pinia vs. Vuex
- mutations no longer exist. They are often considered very verbose . They originally brought devtools integration, but that's no longer an issue.
- There's no need to create custom complex wrappers to support TypeScript, everything is typed, and the API is designed in such a way to leverage TS type inference as much as possible.
- No more injecting, importing functions, calling functions, enjoying autocompletion!
- No need to add Stores dynamically, they are all dynamic by default and you won't even notice. Note that you can still manually register with the Store at any time, but since it's automatic, you don't need to worry about it.
- There is no nested structure of modules anymore . You can still implicitly nest Stores by importing and using them in another Store , but Pinia provides a flat structure by design while still supporting cross-composition between Stores. You can even have a circular dependency of Store .
- There is no namespace module . Given the flat architecture of Stores, "namespaced" Stores are inherent in the way they are defined, and you could say that all Stores are namespaced.
4. Specific usage method
1. Install
Install with your favorite package manager pinia
:
yarn add pinia
# 或者使用 npm
npm install pinia
Introduce store in main.js
import { createApp } from 'vue'
import App from './App.vue'
// 引入pinia
import { createPinia } from 'pinia'
// createApp(App).mount('#app')
// import { createPinia } from 'pinia'
// app.use(createPinia())
const app = createApp(App);
app.use(createPinia())
app.mount('#app');
2. Create a Store
In the src folder of the project root directory - create a store folder - create an index.js file
index.js
Explanation of main - "main" here is equivalent to the unique identifier in stroe
// 定义一个store
import {defineStore} from 'pinia';
export const useStore = defineStore('main',{
})
Use in the page - import in the corresponding page, take main.vue as an example below
// 使用store
import { useStore } from "../store/index";
Five, state
Most of the time, the state is the core part of the store. We usually start by defining the state of the application. In Pinia, states are defined as functions that return an initial state. Pinia works both server-side and client-side.
Data in state in index.js
// 定义一个store
import {defineStore} from 'pinia';
export const useStore = defineStore('main',{
// 定义一个state
state:( )=>{
return {
// 声明一个数组,用来存储每条具体的购物记录
goodsList : [
{ id: 1, title: "手机", price: 100, num: 1, checked: false },
{ id: 2, title: "平板", price: 500, num: 1, checked: false },
{ id: 3, title: "耳机", price: 200, num: 1, checked: false },
]
}
},
})
1. Access state
Take the use in main.vue as an example
use store
// 使用store
import { useStore } from "../store/index";
Use the data in the store
Where is the data in the store at this time?
2. Reset state
Reset the data in the state to its initial value
Use -- store.$reset( )
Button event to reset state
// 重置按钮的点击事件 const reset = ( )=>{ store.$reset() }
As shown in the example below:
3. Change state
Use -- store.$patch( )
Name change button event
const changeName = ( )=>{ store.$patch({ name: store.name = 'hhhh' } ) }
4. Modify state in batches
const changeName = ( )=>{
store.$patch((state)=>{
state.name = 'hhhh'
})
}
5. Replace state
use store.$state = {name: "Tom", age:20}
Six, getters
The Getter is exactly equivalent to the computed value of the Store state . They can be defined with attributes
defineStore()
ingetters
. They accept "state" as the first argument to encourage the use of arrow functions:
1. Access getters
// getters 依赖state中的状态 getters:{ changeName(state){ return state.name = 'Taylor Swift' }, }
Access getters in the page
onMounted(()=>{
store.changeName
})
We modified the values in the getters in gettes, and called the properties in the getters in the onMounted hook. You can see that the properties in the state have been changed when the page is loaded.
2. Getters pass parameters
Getters are just computed properties behind the scenes , so no parameters can be passed to them. However, you can return a function from the getter to accept any arguments:
Call and pass parameters in the page:
<span>{
{store.changeName(1)}}</span>
export const useStore = defineStore('main', { getters: { getUserById: (state) => { return (userId) => state.users.find((user) => user.id === userId) }, }, })
3. Write as a normal function to call this
Most of the time, getters will only depend on state, however, they may need to use other getters.
this
Because of this, we can access the entire store instance when defining regular functions , but need to define the return type (in TypeScript) . This is due to a known limitation in TypeScript, and does not affect getters defined with arrow functions, northis
getters that don't :
4. Access getters in other stores
- Introduce other stores in the current store
// 引入其他的模块 import {useOtherStore} from './other'
- You can call stores in other modules in the current store. In fact, pinia does not need to be modularized like vuex. Every .js file you create is a separate module. You only need to use it when you need to use it on the page. Just import it.
// 访问其他的store中的getter otherGetter(state){ const otherStore = useOtherStore(); return state.name + otherStore.changeHoppy; }
Seven, actions
Actions are equivalent to methods in components . They can be defined using properties
defineStore()
inactions
, and they are great for defining business logic :
1. Access actions
For example, I call the method in actions on the page to change the value in state:
const changeHeight = ( )=>{
store.changeHeight()
}
actions:{
changeHeight(){
this.height ++
}
}
2. Call actions in other stores
The method of calling is the same as the method in the getters above, so I won’t repeat it here!
8. Easter eggs - shopping cart case sharing
Today I learned to use gitee, so that I can host my code on it, and it is also convenient for interested friends to check it out! The address is here:
vue3: use vue3+pinia to realize the shopping cart function
Summarize
The above is what I want to share today. I just reviewed the use of pinia again when I write here. I hope what I wrote can help you. Finally, I still wish you health, happiness, peace and happiness in front of the screen!