Skip to content

Pinia

Pinia是一个全新的Vue状态管理库,是Vuex的代替者,尤雨溪强势推荐

  1. Vue2 和 Vue3 都能支持
  2. 抛弃传统的 Mutations ,只有 state, getteractions ,简化状态管理库
  3. 不需要嵌套模块,符合 Vue3 的 Composition api,让代码扁平化
  4. TypeScript支持
  5. 代码简介,很好的代码自动分割
  6. 足够轻量,压缩后的体积只有1.6kb;

语法

安装

bash
cnpm i pinia@2.0.4 -S

注册

src/main.ts

js
import {createPinia} from 'pinia'
const store = createPinia()
app.use(store)

定义仓库

pinia仓库有三个配置项:

  • state:用来定义数据
  • getters:用来定义计算属性
    • getters里的计算属性有一个形参state,可以通过state.键访问state数据,也可以通过this.键访问
  • actions:用来定义方法

src/store/users.ts

js
// 导入 defineStore
import {defineStore} from 'pinia'
// 标识代表模块化
export const useUserStore = defineStore(标识, {
 	state: () => {		// 定义数据
 		return {
            num:1,
            num2:2
        }
 	},
 	getters: {			// 定义计算属性
        get(state){
            // return this.num+this.num2
            return state.num+state.num2
        }
    },
 	actions: {			//定义方法
 		async fn() {
 			this.state键 = 数据
 		},
        fn2() {
            // 调用自身方法
            this.fn()
        }
 	}
})

使用数据

注意:需要使用storeToRefs()pinia数据变成响应式

vue
<script setup>
    // 导入
    import { useUserStore } from 'src/store/users.ts'
    import { storeToRefs } from 'pinia'
    // 创建store
    const store = useUserStore()

    // 获取state数据
    store.键
    // 获取getters数据
    const = computed( () => store.键 )
    // 获取state数据并变成响应式
    const = ref(store.键)
    // 解构变成响应式
    const {键1,....,键n} = storeToRefs(store)
</script>

使用action中的方法

js
store.action中的方法名()

更新数据

js
// 单条直接改
store.键 = 数据
// 多条批量改
store.$patch({ 
	键: 数据, 
    键2:数据2,
    // ...
})

响应式数据

通过传统的解构赋值,获得的值不具有响应性

需要使用storeToRefs()解构

js
import { storeToRefs } from "pinia";
import { useCommonStore } from "@/store/useCommonStroe";

const commonStore = useCommonStore();

const { num, num2 } = storeToRefs(commonStore);

// 更新单条数据,仍需要使用store.键=?更新
const handleUpd = () => {
    store.num1++
};

// 更新多条数据
const handleUpd = () => {
    commonStore.$patch({
        num: num.value + 1,
        num2: num2.value + 1,
    });
};

函数写法

pinia的函数写法可以使用vue3composition api定义数据

注意:函数写法的每一个需要用到的数据都必须return出去

定义数据

js
import { ref, computed } from 'vue'
import { defineStore } from 'pinia'

export const useCounterStore = defineStore('counter', () => {
  //定义属性
  const num1 = ref(5)
  const num2 = ref(10)

  //定义计算属性
  const sum = computed(() => {
    return num1.value + num2.value
  })

  //定义方法
  const add = () => {
    num1.value++
  }
  return {
    num1,
    num2,
    sum,
    add
  }
})

使用数据

vue
<script setup>
import { useCounterStore } from './stores/counter'
const store = useCounterStore()
// 调用store方法
const addNum1 = () => {
  store.add()
}

// 直接修改store数据
const addNum2 = () => {
  store.num2++
}
</script>

<template>
  <div class="">num1:{{ store.num1 }}</div>
  <div class="">num2:{{ store.num2 }}</div>
  <div class="">num2:{{ store.sum }}</div>
  <button @click="addNum1">num1++</button>
  <button @click="addNum2">num2++</button>
</template>

数据持久化

安装

sh
npm i pinia-plugin-persist

使用

src/main.js

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

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

开启缓存

对象写法

js
export const useUserStore = defineStore({
  id: 'user',

  state: () => {
    return {
      name: '张三'
    }
  },
  
  // 开启数据缓存
  persist: {
    enabled: true
  }
})

函数写法

js
import {ref} from 'vue'
export const useUserStore = defineStore(
    'user',
    ()=>{
        const conut=ref(10)
        return {count}
    },
    {
        persist: {
            enabled: true
        }
    }
)

自定义key

开启数据缓存默认存储在sessionStorage

可以在persiststrategies 里自定义 key 值,并将存放位置由 sessionStorage 改为 localStorage。

js
persist: {
    	enabled: true,
        strategies: [
            {
                key: 'my_user',
                storage: localStorage,
            },
        ]
}

持久化部分state

默认所有 state 都会进行缓存,可以通过 paths 指定要持久化的字段,其他的则不会进行持久化。

js
state: () => {
  return {
    name: '张三',
    age: 18,
    gender: '男'
  }  
},

persist: {
  enabled: true,
  strategies: [
    {
      storage: localStorage,
      paths: ['name', 'age']
    }
  ]
}

上面我们只持久化 name 和 age,并将其改为localStorage, 而 gender 不会被持久化,如果其状态发生更改,页面刷新时将会丢失,重新回到初始状态,而 name 和 age 则不会。

MIT Licensed