手寫一個(gè)Vuex(一)

手寫一個(gè)Vuex,命名為myVuex,替換Vuex的引入,其他使用方法不變。如下內(nèi)容:

import Vue from 'vue';
import myVuex from '../myVuex';
Vue.use(myVuex);

let store = new myVuex.Store({
    state: {
        pageSize: 12,
        test: '',
        ttt: ''
    },
    // commit
    mutations: {
        isCommit(state, val) {
            state.test = val
        }
    },
    // dispatch
    actions: {
        isDispatch(state, val) {
            state.ttt = val
        }
    }
})

export default store;

首先,先創(chuàng)建myVuex文件夾與store文件夾同級(jí)
然后,myVuex文件夾中創(chuàng)建index.js, 由于需要支持Vue.use和new myVuex.Store方法,(Vue.use需要用到install,后面會(huì)介紹;)所以暴露的Vuex需要如下內(nèi)容:

index.js:
let Vuex = {
    install: install,
    Store: store,
    version: '3.1.3'
}

export default Vuex

接下來我們先實(shí)現(xiàn)Vue.use(myVuex),我們先分析一下Vue.use具體做了什么操作,源碼如下:
最主要就是調(diào)用了插件的install方法或自身。

export function initUse(Vue: GlobalAPI) {
  Vue.use = function (plugin: Function | Object) {
    const installedPlugins = (this._installedPlugins || (this._installedPlugins = []))
    if (installedPlugins.indexOf(plugin) > -1) {
      return this
    }

    // additional parameters
    const args = toArray(arguments, 1)
    args.unshift(this)
    // 調(diào)用install方法或自身
    if (typeof plugin.install === 'function') {
      plugin.install.apply(plugin, args)
    } else if (typeof plugin === 'function') {
      plugin.apply(null, args)
    }
    installedPlugins.push(plugin)
    return this
  }
}

所以,我們myVuex中需要增加install方法,如下:

var install = function install(Vue) {
    console.log(Vue)
    console.log(this) // 此處this是Vuex
    // 需判斷是否存在Vue

    applyMixin(Vue)
}

function applyMixin(Vue) {
    // 將vuexInit方法混淆到beforeCreate中,因此每個(gè).vue頁面創(chuàng)建的時(shí)候都會(huì)去調(diào)用vuexInit
    // 所以每個(gè)頁面都可以使用this.$store進(jìn)行訪問
    Vue.mixin({ beforeCreate: vuexInit });
}

// 實(shí)現(xiàn)this.$store的使用
function vuexInit() {
    console.log(this) // 此處this是Vue
    var options = this.$options;

    if (options.store) { // 說明是根節(jié)點(diǎn)
        this.$store = options.store
    } else {
        this.$store = options.parent.$store
    }
}

接著我們講解store,新建store.js文件,專門處理store內(nèi)容:

var Store = function Store(options) {
    console.log(this) // Store本身
    let keys = Object.keys(options);
    for (let item of keys) {
        this[item] = options[item]
    }
}

// prototype屬性指向構(gòu)造函數(shù)創(chuàng)建的實(shí)例的原型對(duì)象,即Store.prototype === new Store().__proto__
Store.prototype.commit = function commit(type, payload) {
    this.mutations[type].call(this, this.state, payload)
}

Store.prototype.dispatch = function dispatch(type, payload) {
    this.actions[type].call(this, this.state, payload)
}

export default Store;

未解決問題:
store的數(shù)據(jù)雙向綁定, 后續(xù)完善。

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

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