Pinia.js使用指南

937 阅读2分钟

前言

pinia是新一代的状态管理工具, pinia 去除了 mutations,只有 state,getters,actions

安装

yarn add pinia -S

创建pinia并引入

在src/store文件下新建一个index.js

// src/store/index.js
import { createPinia } from 'pinia'

const store = createPinia()

export default store
// main.js
import { createApp } from 'vue'
import App from './App.vue'
import store from './store'

const app = createApp(App)
app.use(store)
app.mount('#app')

使用(创建一个store)

在src/store文件新建一个user.js文件

import { defineStore } from 'pinia'

// defineStore方法第一个参数是该store的id,必须唯一
const useUserStore = defineStore('userStore', {
    // state的值必须是一个函数返回一个对象,这里我们使用箭头函数加小括号的方式省略了return
    state: () => ({
        name:''
    }),
    // pinia中没有mutations,可以直接在actions中更改state的值,其中可以直接通过this.xxx获取到state的值
    actions:{
        updateName(name){
            this.name = name 
        }
    }
})

export default useUserStore

在组件中获取state

<template>
    <p>{{ name }}</p>
</template>
<script setup>
import { storeToRefs } from 'pinia'
import useUserStore from '@/store/user.js'
const store = useUserStore()

// 1.直接获取
const name = store.name 

// 2.结合计算属性获取
const name = computed(()=> store.name)

// 3.另外也可以使用解构获取,但是解构会使其失去响应性,这个时候可以用到pinia的storeToRefs方法
const { name } = storeToRefs(store)

// 以上展示了三种获取state的方式,复制代码注意变量重复
</script>

修改state

修改state也有几种方式:

1.直接修改,不推荐

<script setup>
import useUserStore from '@/store/user.js'
const store = useUserStore()

function changeName(){
    store.name = 'xxx'
}
</script>

2.使用$patch修改数据

<script setup>
import useUserStore from '@/store/user.js'
const store = useUserStore()

function changeName(){
    // 使用$patch修改也有两种方式
    // 第一种 $patch方法
    store.$patch({
        name:'xxx'
    })
 
    // 第二种 $patch方法
    store.$patch((state) => {
        state.name = 'xxx'
    })
    // 这两种方法对比,推荐第二种,第二种修改state更灵活,且不易出错
}
</script>

3.使用actions中的方法修改数据-推荐

<script setup>
import useUserStore from '@/store/user.js'
const store = useUserStore()

function changeName(){
    store.updateName('xxx')// 这里使用我们上文在actions中定义的updateName方法
}
</script>

getters

getters就比较简单了

import { defineStore } from 'pinia'

const useUserStore = defineStore('userStore', {
    state: () => ({
        name:'李'
    }),
    getters: {
        fullName(state) => {
            return state.name + '四'
        }
    }
})

export default useUserStore
<script setup>
import useUserStore from '@/store/user.js'
const store = useUserStore()

const fullName = store.fullName
</script>

actions

actions支持async/await异步写法,也可以调用其他actions方法,也可以调用其他store中的actions方法

// src/store/app.js
import { defineStore } from 'pinia'

const useAppStore = defineStore('appStore', {
    actions: {
        setData() {
            consoloe.log('app')
        }
    }
})
export default useAppStore
// src/store/user.js
import { defineStore } from 'pinia'
import useAppStore from './app'
import api form '@/request/api'

const useUserStore = defineStore('userStore', {
    actions: {
        async login(e) {
            const { data } = await api.login(e)
            this.successFn()// 调用其他actions方法
            const appStore = useAppStore()
            appStore.setData(data) // 调用 appStore 里的 action 方法
            return data
        },
        successFn(){
            console.log('成功')
        }
    }
})
export default useUserStore

数据持久化

无论是vuex还是pinia,刷新页面都会丢失state中的动态数据 但是我们可以使用插件pinia-plugin-persist轻松实现数据持久化

安装

yarn add pinia-plugin-persist -S

使用

import { createPinia } from 'pinia'
import piniaPluginPersist from 'pinia-plugin-persist'

const store = createPinia()
store.use(piniaPluginPersist)

export default store

在需要持久化的store中开启persist

export const useUserStore = defineStore('userStore',{
    state: () => ({
        name:'李',
        age:18,
        gender:'男'
    }),
  
    // 数据持久化
    persist: {
        enabled: true //开启数据缓存
        strategies: [
            {
                key'my_user',//自定义key,如果不写,在缓存的key就为defineStore第一个参数名
                storagelocalStorage,// 获取为sessionStorage
                paths: ['name''age']// 定义部分字段缓存
            }
        ]
    }
})