初识Pinia

121 阅读2分钟

Pinia 是状态管理工具。

前言

Pinia主要有以下特征(图片来自Pinia文档):

image.png

简单理解:

  • 不存在mutations
  • TS的类型推断更加明确
  • 不需要额外引入,会自动进行注册
  • 不再有嵌套的模块结构,扁平化结构,不存在 namespaced,定义创建是就是一个单独的模块

安装

npm install pinia

引入

代码实现是基于vue3 + ts

--- main.ts ---
import { createPinia } from 'pinia';
app.use(createPinia())

基本结构

defineStore -- 定义一个store

  • 定义的store变量名称尽量以 useXXX 命名
  • 接收两个参数,第一个参数是id,第二个参数是内容
--- store.ts ---
import { defineStore } from 'pinia';
// const useCommon = defineStore(xxx, {});
// defineStore(id:string, component:object | any)

export const useCommon = defineStore('common', {
    state:() => ({}),
    getters: {},
    actions: {},
});

--- template ---
<script lang='ts' setup>
import { useCommon } from '.......'; // 路径

const commonStore = useCommon();
</script>

state

  • state是一个函数,为了防止变量间的交叉污染(与vue中data作用相似)
  • state是箭头函数,为了更好的ts的类型推断
const useCommon = defineStore('common', {
    state: () => ({
        msg: 'Hello World',
        count: 0,
    }),
})

使用state

方法1:引入后直接使用

<template>
    <div>{{ commonStore.msg }}</div>
</template>

<script lang='ts' setup>
import { useCommon } from '.......';
const commonStore = useCommon();
</script>

方法2:解构赋值

  • 解构赋值会使数据响应的特性消失
  • 要使用 storeToRefs 保持
<template>
    <div>{{ message }}</div>
</template>

<script lang='ts' setup>
import { useCommon } from '.......';
import { storeToRefs } from 'pinia'; // 引入

const commonStore = useCommon();
const { msg: message } = storeToRefs(commonStore); // 使用
</script>

修改state

方法1:通过actions修改(此处暂不展开描述)

方法2:直接修改

  • $patch
// 写法1
commonStore.$patch({
    msg: 'Hello Pinia',
    count: 5,
})

// 写法2
commonStore.$patch((state) => {
    state.count += 1;
    state.msg = 'So Noce'
})

getters

类似于计算属性

  • 当以普通函数写法时,一定要添加 return 的类型
  • 当以箭头函数写法时,传入 state,才能获取 state 中的值并进行修改
export const useCommon = defineStore('common', {
    state: () => ({
        count: 0,
        count1: 10
    }),
    getters: {
        // 写法1
        totalCount():number {
            const total = this.count + this.count1;
            return total
        }
        // 写法2
        totalCount: (state) => {
            return state.count + state.count1
        }
    }
})

使用getters

<template>
    <div>{{ commonStore.totalCount }}</div>
</template>

actions

state的修改

const useCommon = defineStore('common', {
    state: () => ({
        count: 0,
    }),
    actions: {
        changeCount(n1:number) {
            this.count += n1;
        },
    },
})

使用

// 创建按钮的点击事件为btnChange
const btnChange = () => {
  // 调用 useCommon 的 actions 定义的changeCount函数
  commonStore.changeCount(1); 
}

异步

// 创建按钮的点击事件为btnChange
actions: {
    async getNavList() {
        const navRes = await getNavListAPI();
        this.navList = navRes.data.data;
    },
},

调用其他的store中的actions方法

export const useCommon = defineStore('common', {
    state: () => ({
        count: 0,
    }),
    actions: {
        changeCount() {
            // 获取另一个store对象
            const deviceStore = useDevice();
            // 调用另一个store对象的action中的函数
            this.count = deviceStore.changeCount();
        },
    },
})

export const useDevice = defineStore('device', {
    state: () => ({
        devcieCount: 2,
    }),
    actions: {
        changeCount() {
            this.devcieCount += 2;
            return this.devcieCount
        },
    },
})

结语

以上均为根据文档进行一个简单初步的理解,如有错误欢迎各位大佬指出,谢谢