Vuex核心实现原理

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式,可以帮助我们管理共享状态。


image.png

如何在Vue中使用Vuex?

如下先来回顾一下使用Vuex的正确姿势:
1.引入Vuex插件;

// store.js
Vue.use(Vuex);

2.将Vuex.Store这个类实例化,并传入一些配置,这里以计数器作为一个例子;

// store.js
const store = new Vuex.Store({
    state:{
        count:0
    },
    mutations:{
        increment(state){
            state.count++;
        },
        del(state){
            state.count--;
        },
    },
    actions:{
        asyncAdd({commit}){
            setTimeout(() => {
                commit("increment");
            }, 2000);
        }
    }
})

3.将store的实例配置给Vue

new Vue({
  store,
  render: h => h(App),
}).$mount('#app')

4.组件中使用时

<template>
    <div>计数器
        <span>{{$store.state.count}}</span>
        <br/>
        <button @click="this.add">+</button>
        <button @click="this.del">-</button>
        <button @click="this.asyncAdd">异步+</button>
    </div>
</template>
<script>
export default {
    methods:{
        add(){
            this.$store.commit('increment');
        },
        del(){
            this.$store.commit('del');
        },
        asyncAdd(){
            this.$store.dispatch('asyncAdd');
        }
    }
}
</script>

5.效果
页面上点击+时,调用this.$store.commit("xxx")方法,实现this.$store.state.count的修改

Vuex的核心源码解析:

目标:
1.作为插件一定有install方法,可以在其中进行混入,当Vue实例化后挂载前拿到给其配置的store实例,把store放在原型上,以便全局可用;
2.持有基本的state,保存实例化router时配置的mutations,actions对象;
3.实现commit及dispatch等方法,可对state进行一定的修改;

Vuex的核心源码简版:

let Vue;
class Store {
    // 持有state,并使其响应化
    constructor(options){
        this.state = new Vue({
            data:options.state
        })
        this.mutations = options.mutations;// mutations 是对象
        this.actions = options.actions;// mutations 是对象
        // 绑定this
        this.commit=this.commit.bind(this);
        this.dispatch=this.dispatch.bind(this);
    }
    // 实现commit和dispatch方法
    commit(type,arg){
        this.mutations[type](this.state,arg);
    }
    dispatch(type,arg){
        console.log(this.actions[type])
        return this.actions[type](this,arg)
    }
}
function install(_vue){
    Vue = _vue;
    Vue.mixin({// 为什么用混入?use是先执行,而this指向的是vue实例,是在main.js中后创建的,使用混入才能在vue实例的指定周期里拿到store实例并做些事情
        beforeCreate(){
            if (this.$options.store) {
                Vue.prototype.$store=this.$options.store;
            }
        }
    })
}
export default {
    Store,
    install
}

其实,Vuex.Store是个类,使用他的时候,你给他传入了参数(state,mutations,actions)并让他实例化。你把这个实例配置给了Vue,Vuex帮你把他给了Vue原型上的$store。

Vuex还送给你个commit和dispatch方法让你能有办法改$store.state,当然你也能通过$store.state方法到你要的状态。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 安装 npm npm install vuex --save 在一个模块化的打包系统中,您必须显式地通过Vue.u...
    萧玄辞阅读 7,985评论 0 7
  • 上一章总结了 Vuex 的框架原理,这一章我们将从 Vuex 的入口文件开始,分步骤阅读和解析源码。由于 Vuex...
    你的肖同学阅读 5,753评论 3 16
  • ### store 1. Vue 组件中获得 Vuex 状态 ```js //方式一 全局引入单例类 // 创建一...
    芸豆_6a86阅读 4,003评论 0 3
  • vuex 场景重现:一个用户在注册页面注册了手机号码,跳转到登录页面也想拿到这个手机号码,你可以通过vue的组件化...
    sunny519111阅读 12,438评论 4 111
  • 配置 vuex 和 vuex 本地持久化 目录 vuex是什么 vuex 的五个核心概念State 定义状态(变量...
    sunny688阅读 6,831评论 0 23