1. The official website introduces why pinia is used
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({}) . This is true for a single page application, but if it's server-side rendered, makes Your application is exposed to security holes . 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
2. Code practice
2.1. Installation
pnpm add pinia
2.2、main.ts
import { createApp } from 'vue'
import '@/styles/index.less'
import '@/styles/reset.less'
import App from './App.vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import Antd from 'ant-design-vue'
import 'ant-design-vue/dist/antd.css'
import router from "./routers/index";
import { api } from './api/index'
import { createPinia } from 'pinia'
import piniaPersist from 'pinia-plugin-persist' // pinia持久化
import 'vue-global-api';
const app = createApp(App)
const pinia = createPinia()
pinia.use(piniaPersist)
app.use(ElementPlus)
app.use(Antd)
app.use(router)
app.use(pinia)
app.config.globalProperties.$api = api
app.mount('#app')
2.3、src/views/stores/index.ts
import { defineStore } from "pinia";
import { ref, computed } from "vue"
// count1 是 id 须唯一
// options方法
export const useCountStore = defineStore('count1',{
// 在大多数情况下,state 都是你的 store 的核心。人们通常会先定义能代表他们APP 的 state。
// 在 Pinia 中,state 被定义为一个返回初始状态的函数。这使得Pinia 可以同时支持服务端和客户端。
state: () => { // 类似vue2的 data,data(){return{}} 防止服务端数据污染;----推荐使用箭头函数,为了完整类型推理;
return {
// 所有属性将自动推断出他们的类型
counter: 0
}
},
persist: { // 持久化
enabled: true,
},
getters: { // 相当于computed 计算属性
doubleCount (state){
return state.counter * 2
}
},
actions: { // 相当于methods
addCounter(){
// this指向对应的store仓库
this.counter += 1
}
}
})
// count2 是 id 须唯一
// setup方法
export const useCount2Store = defineStore('count2', ()=> {
const counter = ref(1) // state
const gettersCounter = computed(()=>{
return counter.value + 5
})
function addCounter(){
counter.value += 1
}
return { counter, gettersCounter, addCounter}
})
2.4、src/views/pinia/index.vue
<template>
<div class="container">
<div>pinia-options</div>
<div>count1.counter: {
{ count1.counter }}</div>
<div>count1.doubleCount {
{ count1.doubleCount }}</div>
<div @click="count1.addCounter()"> count1.counter: addCount+=1 </div>
<div @click="changeCount1()"> count1.counter: addCount+=2 </div>
<div>pinia-setup</div>
<div>count2.counter: {
{ count2.counter }}</div>
<div>count2.gettersCounter {
{ count2.gettersCounter }}</div>
<div @click="count2.addCounter()"> count2.counter: addCount++ </div>
<div @click="changeCount2()"> count2.counter: addCount+=2 </div>
</div>
</template>
<script setup lang="ts">
import { useCountStore, useCount2Store } from '@/views/stores/index'
const count1 = useCountStore()
const count2 = useCount2Store()
console.log('count1:', count1)
console.log('count2:', count2)
const changeCount1 = () => {
// 方式一、需要修改数据时直接修改
count1.counter += 2
// 方式二、如果需要修改多个,可以使用pinia的$patch方法,推荐使用
// count1.$patch({
// counter: count1.counter += 2
// })
// 方式三、对于复杂的方法可以封装actions的函数
// count1.$patch((state)=>{}
// state.counter = count1.counter += 2
// )
// 方式四、对于复杂的方法可以封装actions的函数
// count1.addCounter
}
const changeCount2 = () => {
count2.counter += 2
}
</script>
<style scoped lang="less">
</style>
2.5. Browser display
3. Welcome to exchange and correct, follow me, and learn together.
reference link