简易的pinia

1 篇文章 0 订阅

pinia是vue的状态管理库。它是一个vue的插件。让我们简单的实现它。

createPinia

我们这样引入它:

import { createPinia } from 'pinia';
app.use(createPinia());

由此,我们可知:createPinia方法的返回值是:一个拥有 install() 方法的对象。所以createPinia函数可以写为:

const createPinia = () => {
    const install = () => {    };
    return {
        install
    }
}

在pinia官网中有这么一句话:创建一个 pinia(根存储)并将其传递给应用程序。所以修改以上代码为:

import { reactive } from 'vue';
const createPinia = () => {
    const rootStore = reactive({}); // 保存所有的store
    // 用于将注册的store添加的rootStore上的方法
    const setRootStore = (name, store) =>{
        // 如果name不存在则添加
        if(!rootStore[name]) {
            rootStore[name] = store;
        }
        return rootStore;
    }
    const install = (app) => {
        app.provide('setRootStore', setRootStore); // 将setRootStore提供给种鸽应用
    };
    return {
        install
    }
}

defineStore

我们一般这样使用它:

import { defineStore } from 'pinia';
const useStore = defineStore('store', {
    state: () => ({
        name: 'pinia',
    }),
    getters: {
        getName() { return this.name; }
    },
    actions: {
        setName(name) { this.name = name; }
    }
})
// =======================================================
import { useStore } from './store';
const store = useStore();
const setNameHandle = () => { store.setName('名字'); }

由此,我们可知:defineStore函数接收两个参数:

        1. 字符串,表示当前store的名称;

        2. 对象,配置state,getters,actions

它的返回值是一个函数,这个函数执行之后,会得到useStore中的state,getters,actions,并且它们都是响应式的,所以defineStore函数可以写为:

import { reactive, toRef, computed } from 'vue';
const defineStore = (name, { state, getters, actions } = options) => {
    const store = {}
    // 将state上的属性转化为响应式
    if(state && typeOf state === 'funtion') {
        const _state = state();
        store.$state = reactive(_state); // 保存this
        for(let key in _state) {
            store[key] = toRef(store.$state, key);    
        }
    }
    // 将getters转化为计算属性
    if(getters && Object.keys(getters).length > 0) {
        for(let getter in getters) {
            // bind中的第一个参数是this指向,第二个参数是getters的方法中的参数
            store[getter] = computed(getters[getter].bind(store.$state, store.$state))
        }
    }
    // 将actions中的方法添加到store上
    if(actions && Object.keys(actions).length > 0) {
        for(let method in actions) {
            store[method] = actions[methos];
        }
    }

    return () => {
        return reactive(store);
    }
}

以上代码为单个的store,我们现在需要将单个的store添加到rootStore上去,并且给它添加一个修改state的方法:$patch。

import { reactive, toRef, computed, inject } from 'vue';
const defineStore = (name, { state, getters, actions } = options) => {
    const store = {}
    // 将state上的属性转化为响应式
    if(state && typeOf state === 'funtion') {
        const _state = state();
        store.$state = reactive(_state); // 保存this
        for(let key in _state) {
            store[key] = toRef(store.$state, key);    
        }
    }
    // 将getters转化为计算属性
    if(getters && Object.keys(getters).length > 0) {
        for(let getter in getters) {
            // bind中的第一个参数是this指向,第二个参数是getters的方法中的参数
            store[getter] = computed(getters[getter].bind(store.$state, store.$state))
        }
    }
    // 将actions中的方法添加到store上
    if(actions && Object.keys(actions).length > 0) {
        for(let method in actions) {
            store[method] = actions[methos];
        }
    }

    return () => {
        const setRootStoreHanle = inject('setRootStore'); // 得到setRootStore方法
        const rootStore = setRootStoreHandle(name, reactive(store)); // 将store添加的rootStore上
        const currentStore = rootStore[name];
        currentStore.$patch = patch; // 添加patch方法
        return currentStore;
    }
}

function patch(value) {
    for(let key in value) {
        this[key] = value[key];
    }
}

这样,一个及其简单的pinia就完成了。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

暗语1998

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值