面試不要怕,最清晰簡潔的手寫Vuex,保證有眼睛就能看懂

GIF 2021-4-23 22-46-17.gif

開始

MyVuex.js源碼,這里為了避免和已經(jīng)導(dǎo)入Vuex的項目沖突,所以名字有區(qū)別

let instance = null
class Mvx {
    store = {
        state: null
    }
    constructor(Vue) {
        const that = this
        this.store.state = new Vue({
            data() {
                return {
                    name: 12
                }
            }
        })
        this.store.commit = {
            SET_NAME(value) {
                that.store.state.name = that.store.state.name + value
            },
            ASYNC_SET_NAME(value) {
                return new Promise(resolve => {
                    setTimeout(() => {
                        that.store.state.name = that.store.state.name + value
                        resolve(that.store.state.name)
                    }, 1000)
                })
            }
        }
        /* 或者用Vue.prototype.$mstore = store,混入的形式是掛在實例上,prototype是在原型上,混入的化感覺性能更好 */
        Vue.mixin({
            beforeCreate() {
                this.$mstore = that.store
            }
        })
    }
}

export const mapStates = (status) => {
    let state = {}
    status.forEach(s => {
        state[s] = () => instance.store.state[s]
    })
    return state
}
export const mapActions = (actions) => {
    let action = {}
    actions.forEach(a => {
        action[a] = instance.store.commit[a]
    })
    return action
}
export default {
    install(Vue) {
        instance = new Mvx(Vue)
        return instance
    }
}

如何使用?

在main.js內(nèi)導(dǎo)入我的Vuex

import Mvx from './MyVuex'
Vue.use(Mvx)

template模板中,測試從實例直接使用和map state和action之后使用

<template>
    <section class="">
        <p class="fsize fcorg pt10 pb10">
            <span class="fcgreen">$mstore.state.name : </span>{{$mstore.state.name}}
        </p>
        <p class="fsize fcorg pt10 pb10">
            <span class="fcgreen">map name : </span>{{name}}
        </p>
        <el-button @click="changeName" size="small" type="success">change name</el-button>
        <el-button @click="SET_NAME(100)" size="small" type="primary">change name By mapActions</el-button>
        <el-button @click="ASYNC_SET_NAME(10)" size="small" type="warning">By AsyncMapAction</el-button>
    </section>
</template>

在模板中使用

// 導(dǎo)入
import { mapStates, mapActions } from '../MyVuex'
export default {
    name: '/test-my-vuex',
    data() {
        return {}
    },
    computed: {
        /* 通過計算屬性,map到data */
        ...mapStates(['name'])
    },
    methods: {
        /* 通過mapActions,map到methods中。測試:1.直接調(diào)用,2.異步調(diào)用,3.直接通過實例調(diào)用 */
        ...mapActions(['SET_NAME', 'ASYNC_SET_NAME']),
        changeName() {
            this.$mstore.commit.SET_NAME(12)
        }
    }
}

推介一下自己的基于Vue2.6的蘭陵王框架https://lanling.diumx.com 和 基于Vue3+Ts+Vite的花木蘭框架http://mulan.diumx.com

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容