Pinia
Vue3 官方推荐的状态管理库
Vue React (数据通信方案)通用思路
props + 事件
Vue: 使用provide,inject 两个API
React: 使用context,useContext 两个API
单组件
- 有两个基本东西,一个是
props,一个是ref/reactive,从外部得到的props,内部的数据就可以放到ref/reactive
两个组件(有三种情况)
父子关系
- 子组件会用
props来获取到父组件的一些数据,一般来说,我们会把父组件的ref/reactive传给子组件,作为子组件的props,也可以把父组件的数据传给子组件,子组件也有自己的ref/reactive。
会有两种情况
- 假设有个数据叫做
me/currentUser,很多组件需要使用,多组件共用一个数据, 父组件请求服务器的数据,放到自己的ref/reactive里面,子组件同父组件,但是会出现请求过多和数据冗长(无人采用)
- 让父组件去请求,请求之后将数据放在
ref/reactive里面,父组件可以对它进行读和写,子组件通过props来读不写,如果要写需要触发emit,请求父组件把me修改一下,把最新的值放在后面,父组件接收到了请求就会监听,得到User2,把User2赋值到me上面(两个组件对同一个数据的读写)
爷孙关系
-
爷爷将
props传给父组件,父组件再将props传给子组件(太弱智,无人用) -
在Vue里面,想要跨组件传输,就使用依赖注入,在爷组件里使用
provide,在子组件里使用inject,但需要同名依赖植入(如provide 'me',inject 'me') -
爷孙之间的跨组件更新:例如修改
me/currentUser的东西放在provide('setMe'),然后子组件inject('setMe')
兄弟关系
- 假如两个组件都需要用到
me/currentUser这个对象,都不能各自发送请求,所以,借助父子组件让两个的父组件去发请求,得到对象,把me分别传给两个组件,修改时都要触发emit('update:me')
远房关系
- 只需要在父组件里
provide(...),然后在子组件和远房组件里inject一下即可,只要有依赖注入就可以做数据管理
- 可以把所有的读写接口
provide到上下文中,该用的时候即可使用。
Vue3 独有的方式
-
const store = reactive/ref .... -
全局的
store、ref/reactive,然后引用。
假设创建 me.js 文件,组件① 和组件② 即可对me.js文件进行读和写,Vue的ref是可以存在于组件之外的,而react则不行。
Pinia/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) 是一个保存状态和业务逻辑的实体,它并不与你的组件树绑定。换句话说,它承载着全局状态。它有点像一个永远存在的组件,每个组件都可以读取和写入它。它有三个概念,state、getter 和 action,我们可以假设这些概念相当于组件中的
data、computed和methods。
Pinia的ID
-
如果两个store的ID一样,那么它的数据就直接复用。
-
如果ID是固定的,则共享数据。
-
如果ID不固定:① 但ID相等,则共享;② 若不相等,则不共享。
Pinia的持久化(暂时的)
- 持久化表现在打开页面,跳转时,列表页面已死,但列表页面的数据没有死,是因为第一页的页面数据都在Pinia里面,组件已死。(如果没有用Pinia的话,数据及页面都没有了)
一个页面的内存只有在刷新新页面时重置,不刷新就永远在那里
- Pinia会默认持久化,需要根据自己的需求来选择使用
为什么说Pinia的持久化是暂时的?
- 因为一刷新页面所有的持久化就没有,如果想要真正的持久化,可以把Pinia的所有数据存到LocalStorage里面,在页面加载的时候,把所有的数据搞到Pinia里面。