当前位置:首页 > 编程笔记 > 正文
已解决

【vue3】Pinia是什么?实现原理?手写Pinia!

来自网友在路上 179879提问 提问时间:2023-11-10 17:33:34阅读次数: 79

最佳答案 问答题库798位专家为你答疑解惑

前言:

本文只是说明pinia的核心功能及核心原理,它本身的功能是很多很复杂的,这里就不进行叙述,我们只需要掌握这个工具的核心功能即可。

1.是什么

Pinia是基于Vue 3的Composition API构建的状态管理库。它让你能够创建和管理多个store,通过调用createPinia激活一次,你能获取全应用的store访问权限。

2.主要特性

  • Pinia拥有独立的store,每个store都有自己的状态(state)和行为(action)等。
  • 你能调用store = useStore()直接使用和获取store。
  • Pinia全局只需要一次安装(通过app.use(createPinia())函数)。
  • 自动在DevTools中显示每次状态改变。

3.实现原理 

以下是对 Pinia 工作原理的总结:

1. 创建 Pinia 实例:   
   `createPinia()` 用于生成 Pinia 实例,这个实例你可以将其看作为一个全局的 store 容器,用来保存所有的 Vuex store。

2. 创建 Store:  
   使用 `createStore` 可以创建一个新的 store,这个 store 可看做是一个独立的状态管理空间,其中包含了 state、getters 和 actions,被创建的 store 实例会被自动添加到 Pinia 实例中。

3. 使用 Store:  
   我们通过在组件中调用用 `createStore` 创建的 store 函数,来获取对应的 Pinia store 的实例。然后,我们就可以访问其中的 state、getters,或者执行 actions 里定义的方法。

4. 监听 Store 变化:  
   我们可以使用 Vue 的 `watch` 和 `watchEffect` 函数来监听 store 中 state 或 getters 的变化,以便在这些内容改变时执行相应的操作。

5. 整合到 Vue App 中:  
   创建的 Pinia 实例需要使用 `app.use()` 安装到 Vue App 中,以便 Pinia 与 Vue App 一同工作,提供全局的状态管理能力。

ps:

如果你已经熟悉 Vue 或 Vuex,那么你在学习和使用 Pinia 时应该会觉得很自然,因为其设计思想和使用方式与 Vue、Vuex 非常接近,但同时也提供了更加灵活和便利的特性。

 


 

3.手写pinia

简易版 Pinia 的实现中包括以下关键部分:

  1. 创建一个 Pinia 对象,它包含一个响应式的 Map,用于存储所有的 store。
  2. 设定在 Vue 类型系统 的安装方法,它将 Pinia 实例提供给整个 Vue 应用。
  3. 设定一个 createStore 方法,用于创建或获取一个 store。store 是通过处理选项参数(如:id, state, getters, actions)生成的。
  4. 设定一个 useStore 方法,通过 store id 来获取 store。使用 computed() 函数确保返回的 store 是响应式的。

具体代码实现: 

// 引入所需的 Vue Composition API 相关函数
import { createStore as createVuexStore, reactive, computed } from 'vue'// 创建 Pinia 对象
function createPinia() {// 用 reactive 创建响应式存储对象const stores = reactive(new Map());return {// 安装 Pinia 到 Vue 应用install(app) {// 在 Vue 应用中注册 Pinia 实例app.provide('pinia', this);},// 创建名为 "createStore" 的方法,用于根据选项创建或获取 storecreateStore(options) {// 如果 stores 已经存在相应的 store,则直接返回这个 storeif (stores.has(options.id)) {return stores.get(options.id);}// 使用 Vue createVuexStore 函数创建响应式 storeconst store = createVuexStore({id: options.id,state: options.state,getters: options.getters,actions: options.actions});// 将新创建的 store 添加到 stores 中stores.set(options.id, store);// 返回创建的 storereturn store;},// 使用 store 的名字获取 storeuseStore(id) {// 返回一个计算属性,其值为获取到的 storereturn computed(() => stores.get(id));}}
}// 创建 Store
function createStore(options) {// 返回一个使用 store 的函数,需要在 setup() 中调用return function useStore(pinia = inject('pinia')) {// 调用 pinia 的 createStore 方法创建或获取对应的 storereturn pinia.createStore(options);}
}export {createPinia,createStore
}

然后,是它的实际使用了:
 

  1. 首先,我们要在应用层面使用 createPinia 创建 Pinia 实例并安装到 Vue 应用中:
    import { createApp } from 'vue';
    import App from './App.vue';
    import { createPinia } from './pinia';// 创建 Pinia 实例
    const pinia = createPinia();// 创建 Vue 应用
    const app = createApp(App);// 使用 Pinia
    app.use(pinia);// 挂载到 DOM
    app.mount('#app');

  2. 然后,我们可以通过 createStore 方法创建一个名为 useCounterStore 的 store:
    import { createStore } from './pinia';export const useCounterStore = createStore({id: 'counter',state: () => ({count: 0}),getters: {isZero: state => state.count === 0},actions: {increment() {this.state.count++;}}
    });

  3. 在 Vue 组件中,可以使用 useCounterStore 来获取和使用这个 store:
    import { computed } from 'vue';
    import { useCounterStore } from './store';export default {setup() {const store = useCounterStore();// 使用状态console.log(store.state.count); // 0// 使用 getter 计算属性const isZero = computed(() => store.getters.isZero);console.log(isZero.value); // true// 使用 actionsstore.actions.increment();console.log(store.state.count); // 1}

    上文中已经描述了 get、set 和使用 store 中的 actions 的基本用法,下面我将说明如果你要监听store的变化应该如何操作。

    Vue 的 Composition API 提供了 `watch` 和 `watchEffect` 函数,能让你监听 reactive object (响应式对象)或者 ref (引用对象)的值变化。当你需要监听 store 中的数据变化时,可以使用这两个函数。

    以下示例展示了如何监听 state 和 getters 的变化:

    
    import { watch, watchEffect } from 'vue';
    import { useCounterStore } from './store';export default {setup() {const store = useCounterStore();// 监听 state 变化watch(() => store.state.count, (newCount, oldCount) => {console.log(`Count changed from ${oldCount} to ${newCount}`);});// 监听 getter 变化watch(() => store.getters.isZero, newVal => {console.log(`isZero changed to ${newVal}`);});// 使用 watchEffect 监听 state 变化,不需要提供一个函数作为源watchEffect(() => {console.log(`Count is now ${store.state.count}`);});}
    }
    

    在这个例子中,我们使用 `watch` 监听 count 和 isZero 的变化,当这两个值改变时,对应的回调函数就会被执行。同时我们也用 `watchEffect` 监听了 count,这样只要 count 变化,即使值还是原值,对应的回调函数也会执行。当你在组件 setup 函数中设置了监听,当组件卸载后,监听也会自动停止。


     

查看全文

99%的人还看了

猜你感兴趣

版权申明

本文"【vue3】Pinia是什么?实现原理?手写Pinia!":http://eshow365.cn/6-37347-0.html 内容来自互联网,请自行判断内容的正确性。如有侵权请联系我们,立即删除!