• vue2手写vuex


    4.29 手写 vuex

    let Vue 
    class Store{
        constructor(options){
            // step1 step1注册$store后让页面能正常显示state
            // this.state = options.state
    
    
            // step2实现mutations actions commit dispatch 
            // step2-01 初步实现mutations actions commit dispatch 
            this._mutations = options.mutations
            this._actions = options.actions 
    
            // step2-02 锁死commit和dispatch的this指向
            this.commit = this.commit.bind(this)
            this.dispatch = this.dispatch.bind(this)
    
    
            // step2-03 让state响应 触发render组件重新渲染
            // 如何造响应式数据?
            // 方式1:借鸡生蛋 - new Vue({data: {XXX: '/'}})
            // 方式2:Vue.util.defineReactive(obj, 'XXX', '/')
            // step2-03 让state变成响应式 同时state不可以随意改变
            this._vm = new Vue({
                data:{
                    // Vue约定:以 _ 或 $ 开头的属性 不会 被 Vue 实例代理
                    $$state : options.state
                }
            })
        }
    
        // step2-03 让state变成响应式 同时state不可以随意改变
        get state(){
            return this._vm._data.$$state
        }
    
        set state(v){
            console.error('请使用replaceState重置状态');
        }
    
        // step2-01 初步实现mutations actions commit dispatch
        commit(type,payload){
            console.log('in commit:',this.state)
            const mutation = this._mutations[type]
            if(!mutation){
                console.error('mutation不存在')
                return
            }
            mutation(this.state,payload)
        }
        dispatch(type,payload){
            const action = this._actions[type]
            if(!action){
                console.error('action不存在')
                return
            }
            // 为什么第一个是this,也就是Store,因为action中需要commit,可以在Store拿到
            action(this,payload)
            // 报错  Cannot read property 'state' of undefined
            // 由于dispatch通常是异步的,所以会异步commit。而commit依赖this.state,但是异步容易丢失上下文,所以我们在constructor中锁死commit和dispatch的this指向 ===》 step2-02
        }
        // OK step2已经完成 但是我们可以发现一个问题 页面上state不会变化,我们需要让Store.state变成响应式数据,触发Vue的render组件渲染 ===》step2-03
    }
    
    // 入口:install 
    function install(_Vue){
        // 保存Vue
        Vue = _Vue
        // step1注册$store
        Vue.mixin({
            beforeCreate(){ 
                /**
                 * this.$options用来访问main.js中
                   new Vue({
                        render: h => h(App),
                        store,
                    })中的options 这里我们是要拿到store
                 */
                if(this.$options.store)Vue.prototype.$store = this.$options.store
            }
        })
        
    }
    export default {Store,install}
    

      

  • 相关阅读:
    Java程序语言的后门-反射机制
    JAVA设计模式-单例模式(Singleton)线程安全与效率
    JAVA设计模式-动态代理(Proxy)源码分析
    Mybatis源码解析,一步一步从浅入深(七):执行查询
    Mybatis源码解析,一步一步从浅入深(六):映射代理类的获取
    python程序中的进程操作
    进程
    操作系统的发展史
    详尽实用的 PyCharm 教程
    python的socketserver模块实现TCP/UDP并发
  • 原文地址:https://www.cnblogs.com/BlueCc/p/14721473.html
Copyright © 2020-2023  润新知