目录

一、pinia是干嘛的

二、安装Pinia

三、封装pinia

四、定义store

五、Store三个核心概念

1、第一个核心概念State

(1)使用state中的数据

(2)直接修改state中的数据

(3)$patch方法修改

(4)$state()方法替换state

(5)$reset() 方法重置state

2、第二个核心概念Getters

(1)定义getters

(2)页面中使用getters

3、第三个核心概念Action

(1)定义action

(2)使用action

三、pinia持久化存储

1、安装持久化插件pinia-plugin-persistedstate

(1)安装依赖

(2)将插件添加到 pinia 实例上

(3)用法

1.基本使用

 2.高级使用



一、pinia是干嘛的

Pinia是 Vue 的存储库,它允许您跨组件/页面共享状态,与vuex功能一样。

二、安装Pinia

yarn add pinia
# 或者使用 npm
npm install pinia

三、封装pinia

封装的作用:Pinia创建和pinia持久化插件引入都在这里做,(文章最后会介绍pinia持久化插件的使用),减少main.js代码的冗余 

1、在src目录下创建stores文件夹,在文件夹下创建index.js文件。

2、index.js文件中写入

import { createPinia } from "pinia" //引入pinia

const pinia = createPinia() //创建pinia实例

export default pinia //导出pinia用于main.js注册

3、main.js中引入使用

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import './assets/reset.css'
import ElementPlus from 'element-plus'
import pinia from './stores'  //引入
 

createApp(App).use(pinia).use(router).use(router).mount('#app')  //使用

四、定义store

1、在stores文件夹下创建一个store ,名为user.js ,命名是尽量是见名知意的。

2、定义user.js

  •  Store 是使用 defineStore() 定义的,并且它需要一个唯一名称,作为第一个参数传递
  • 这个 name,也称为 id,是必要的,Pinia 使用它来将 store 连接到 devtools。 将返回的函数命名为 use... 是跨可组合项的约定
import { defineStore } from "pinia"
 
const useUserInfoStore = defineStore('userInfo', {
  // defineStore('userInfo',{})  userInfo就是这个仓库的名称name
  state: () => ({
    username: '赫赫',
    age: 30,
    like: 'girl',
    obj:{ money:100,friend:10 },
    hobby: [
       { id: 1, name: '篮球', level: 1 },  
       { id: 2, name: 'rap', level: 10 }
     ]
  })
})
 
export default useUserInfoStore

五、Store三个核心概念

1、第一个核心概念State

State类似于组件中的data

(1)使用state中的数据

  • Store在它被使用之前是不会创建的,我们可以通过调用use函数来使用Store。
  • 一旦 store 被实例化,你就可以直接在 store 上访问 stategetters 和 actions 中定义的任何属性
  • store 是一个用reactive 包裹的对象,这意味着不需要在getter 之后写.value,但是,就像setup 中的props 一样,我们不能对其进行解构

tips:不要使用结构赋值的方式取数据,会让数据失去响应式的特性。

<template>
  <!-- state的使用 -->
  <div>我叫 {{ username }},我今年 {{ age }} 岁啦, 喜欢 {{ like }}</div>
  <div>爱好有</div>
  <div v-for="item in hobby" :key="item.id">
    <div>{{ item.name }}</div>
  </div>
  <button @click="editPiniaHandler">点击修改</button>
  <button @click="editAll">点击修改全部</button>
  <button @click="replaceAll">替换</button>
</template>

<script setup>
import { ref, toRefs } from "vue";
import useUserInfoStore from "@/stores/user"; //引入仓库
import { storeToRefs } from "pinia"; //引入pinia转换
const userInfoStore = useUserInfoStore();

// const { username, age, like, hobby } = userInfoStore //直接结构赋值  不是响应式
// const { username ,age, like, hobby } = toRefs(userInfoStore) // 响应式
const { username, age, like, hobby } = storeToRefs(userInfoStore); // 响应式
</script>

(2)直接修改state中的数据

tips:修改相应的属性值

// 一个一个修改
const editPiniaHandler = () => {
  userInfoStore.username += "嘎";
  userInfoStore.age += 1;
  userInfoStore.like = "boy";
};

(3)$patch方法修改

tips:修改相应的属性值

//使用$patch方法  以对象的形式一次性修改
const editAll = () => {
  userInfoStore.$patch({
    username: "鸭蛋",
    age: 21,
  });
};

(4)$state()方法替换state

tips:替换相应的属性值

// $state  替换 state 为新对象
const replaceAll = ()=> {
    userInfo.$state = {
    name: '狗子',
    age: '22',
    like: 'boy',
    obj:{ money:10, friend:1 }
  }
}

(5)$reset() 方法重置state

tips:整个state的属性值都会变成定义时的初始值

// 重置state
const resetBtn = ()=> {
  userInfoStore.$reset()
}

2、第二个核心概念Getters

  • Getters类似于组件中的计算属性
  • Getters 只是幕后的 computed 属性,因此无法向它们传递任何参数。 但是,您可以从 getter 返回一个函数以接受任何参数

(1)定义getters

 书接上文:getters定义与上文中的state同级书写

import { defineStore } from "pinia"
 
const useUserInfoStore = defineStore('userInfo', {
  // defineStore('userInfo',{})  userInfo就是这个仓库的名称name
  state: () => ({
    username: '赫赫',
    age: 30,
    like: 'girl',
    obj:{ money:100,friend:10 },
    hobby: [
       { id: 1, name: '篮球', level: 1 },  
       { id: 2, name: 'rap', level: 10 }
     ]
  }),
  getters: {
        // 类似于计算属性,参数state指向defineStore下的state
        doubleAge(state) {
            return state.age * 2
        },
        //在getter中 使用另一个getter  this指向当前存储库
        addOneAge() {
            return this.doubleAge + 1
        },
        //返回一个函数
        returnFunction(state) {
            return function (id) {
                return state.hobby.find(item => item.id == id)
            }
        }
    },
})
 
export default useUserInfoStore

(2)页面中使用getters

<template>
  <!-- getter的使用 -->
  <div>乘2: {{ userInfoStore.doubleAge }}</div>
  <div>加一: {{ userInfoStore.addOneAge }}</div>
  <div>返回一个函数查找id为1的爱好: {{ userInfoStore.returnFunction(1) }}</div>
</template>

3、第三个核心概念Action

Actions 相当于组件中的 methods。 它们可以使用 defineStore() 中的 actions 属性定义,并且它们非常适合定义业务逻辑

tips:Actions支持异步操作的,可以编写异步函数

(1)定义action

书接上文:action定义与上文中的state、getter同级书写,下面的代码不再赘述

//可以通过this访问整个store实例的所有操作,支持异步操作
    actions: {
        //非异步操作
        addAge(e) {
            console.log('接受的数据', e) //e是外部调用方法传递的参数
            this.age = this.age + e
        },
        // 模拟异步
        asynchronous() {
            return new Promise((resolve)=> {
                setTimeout(() => {
                    resolve('模拟异步返回值')
                }, 2000);
            })
        },
        // 异步操作
        async getList () {
            const res = await this.asynchronous()
            console.log(res)
        }
    },

(2)使用action

// 调用action中的方法
const add = ()=> {
  userInfoStore.addAge(5)
}
//调用异步方法
const getLisst = ()=> {
  userInfoStore.getList()
}

三、pinia持久化存储

1、安装持久化插件pinia-plugin-persistedstate

tips:官网连接

快速开始 | pinia-plugin-persistedstate (prazdevs.github.io)

(1)安装依赖

npm i pinia-plugin-persistedstate

yarn add pinia-plugin-persistedstate

pnpm i pinia-plugin-persistedstate

(2)将插件添加到 pinia 实例上

tips:在上面封装的 index.js 文件基础上,引入插件并使用。

import { createPinia } from "pinia" //引入pinia
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate' //引入持久化插件

const pinia = createPinia() //创建pinia实例
pinia.use(piniaPluginPersistedstate) //将插件添加到 pinia 实例上

export default pinia //导出pinia用于main.js注册

(3)用法

书接上文:action定义与上文中的state、getter、action同级书写

1.基本使用

创建 Store 时,将 persist 选项设置为 true,整个 Store 将使用默认持久化配置保存。

默认持久化配置:

  • 使用 localStorage进行存储
  • store.$id作为 storage 默认的 key
  • 使用 JSON.stringify / JSON.parse进行序列化/反序列化
  • 整个 state 默认将被持久化
import { defineStore } from "pinia"
 
const useUserInfoStore = defineStore('userInfo', {
  // defineStore('userInfo',{})  userInfo就是这个仓库的名称name
  state: () => ({
    username:'赫赫',
    age: 23,
    like: 'girl',
  }),
  getters: {
        ...........
  },
  action:{
    .........
  },
  persist: true,
})
 
export default useUserInfoStore
 2.高级使用

如何你不想使用默认的配置,那么可以将一个对象传递给 Store 的 persist 属性来配置持久化

 介绍三个常用属性:

key:存储名称。

storage:存储方式。

path:用于指定 state 中哪些数据需要被持久化。[] 表示不持久化任何状态,undefined 或 null 表示持久化整个 state。


import { defineStore } from "pinia"
 
const useUserInfoStore = defineStore('userInfo', {
  // defineStore('userInfo',{})  userInfo就是这个仓库的名称name
  state: () => ({
    username:'赫赫',
    age: 23,
    like: 'girl',
    obj:{ money:100,friend:10 }
  }),
  getters: {
        ...........
  },
  action:{
    .........
  },
  persist: {
      key: 'piniaStore', //存储名称
      storage: sessionStorage, // 存储方式
      paths: ['username', 'like','obj'], //指定 state 中哪些数据需要被持久化。[] 表示不持久化任何状态,undefined 或 null 表示持久化整个 state
  },
})
 
export default useUserInfoStore

 效果如图:

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐