Pinia 的使用

694 阅读4分钟

Pinia

Vue3 官方推荐的状态管理库

Pinia 官方文档

Vue React (数据通信方案)通用思路

  • props + 事件

Vue: 使用provideinject 两个API

React: 使用contextuseContext 两个API

单组件

  • 有两个基本东西,一个是props,一个是ref/reactive,从外部得到的props,内部的数据就可以放到ref/reactive

image.png

两个组件(有三种情况)

父子关系

  • 子组件会用props来获取到父组件的一些数据,一般来说,我们会把父组件的ref/reactive传给子组件,作为子组件的props,也可以把父组件的数据传给子组件,子组件也有自己的ref/reactive

会有两种情况

  1. 假设有个数据叫做 me/currentUser,很多组件需要使用,多组件共用一个数据, 父组件请求服务器的数据,放到自己的ref/reactive里面,子组件同父组件,但是会出现请求过多数据冗长(无人采用)

image.png

  1. 让父组件去请求,请求之后将数据放在ref/reactive里面,父组件可以对它进行读和写,子组件通过props来读不写,如果要写需要触发emit,请求父组件把me修改一下,把最新的值放在后面,父组件接收到了请求就会监听,得到User2,把User2赋值到me上面(两个组件对同一个数据的读写

image.png

爷孙关系
  • 爷爷将props传给父组件,父组件再将props传给子组件(太弱智,无人用)

  • 在Vue里面,想要跨组件传输,就使用依赖注入,在爷组件里使用 provide ,在子组件里使用 inject,但需要同名依赖植入(如 provide 'me'inject 'me')

  • 爷孙之间的跨组件更新:例如修改me/currentUser的东西放在 provide('setMe'),然后子组件inject('setMe')

兄弟关系

  • 假如两个组件都需要用到me/currentUser这个对象,都不能各自发送请求,所以,借助父子组件让两个的父组件去发请求,得到对象,把me分别传给两个组件,修改时都要触发emit('update:me')

image.png

远房关系

  • 只需要在父组件里 provide(...),然后在子组件和远房组件里 inject 一下即可,只要有依赖注入就可以做数据管理

image.png

  • 可以把所有的读写接口 provide 到上下文中,该用的时候即可使用。

Vue3 独有的方式

  • const store = reactive/ref ....

  • 全局的 storeref/reactive,然后引用。

image.png

假设创建 me.js 文件,组件① 和组件② 即可对me.js文件进行读和写,Vueref是可以存在于组件之外的,而react则不行。

Pinia/Zustand

Zustand 文档

Pinia解决了第二个Vue3独有的方案的跨请求污染

什么是Pinia?

  • Pinia 是 Vue 的专属状态管理库,它允许你跨组件或页面共享状态。如果你熟悉组合式 API 的话,你可能会认为可以通过一行简单的 export const state = reactive({}) 来共享一个全局状态。对于单页应用来说确实可以,但如果应用在服务器端渲染,这可能会使你的应用暴露出一些安全漏洞(这个安全漏洞是跨请求污染),而如果使用 Pinia,即使在小型单页应用中,你也可以获得如下功能:

  • Devtools 支持

    • 追踪 actions、mutations 的时间线
    • 在组件中展示它们所用到的 Store
    • 让调试更容易的 Time travel
  • 热更新

    • 不必重载页面即可修改 Store
    • 开发时可保持当前的 State
  • 插件:可通过插件扩展 Pinia 功能

  • 为 JS 开发者提供适当的 TypeScript 支持以及自动补全功能。

  • 支持服务端渲染

安装Pinia

yarn add pinia 
或者使用 
npm npm install pinia

创建Pinia的实例(根store)并将其传递给应用

import { createApp } from 'vue' 

import { createPinia } from 'pinia' 

import App from './App.vue' 

const pinia = createPinia()  //定义Pinia

const app = createApp(App) 

app.use(pinia)   //使用Pinia

app.mount('#app')

Store是什么?

  • Store (如 Pinia) 是一个保存状态和业务逻辑的实体,它并不与你的组件树绑定。换句话说,它承载着全局状态。它有点像一个永远存在的组件,每个组件都可以读取和写入它。它有三个概念stategetter 和 action,我们可以假设这些概念相当于组件中的 data、 computed 和 methods

Pinia的ID

  • 如果两个store的ID一样,那么它的数据就直接复用。

  • 如果ID是固定的,则共享数据。

  • 如果ID不固定:① 但ID相等,则共享;② 若不相等,则不共享。

Pinia的持久化(暂时的)

  • 持久化表现在打开页面,跳转时,列表页面已死,但列表页面的数据没有死,是因为第一页的页面数据都在Pinia里面,组件已死。(如果没有用Pinia的话,数据及页面都没有了)

一个页面的内存只有在刷新新页面时重置,不刷新就永远在那里

  • Pinia会默认持久化,需要根据自己的需求来选择使用

为什么说Pinia的持久化是暂时的?

  • 因为一刷新页面所有的持久化就没有,如果想要真正的持久化,可以把Pinia的所有数据存到LocalStorage里面,在页面加载的时候,把所有的数据搞到Pinia里面。

参考文档