亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

JS每日一題: 請(qǐng)簡(jiǎn)述一下vuex實(shí)現(xiàn)原理

JohnLui / 1396人閱讀

摘要:給的實(shí)例注入一個(gè)的屬性,這也就是為什么我們?cè)诘慕M件中可以通過(guò)訪問(wèn)到的各種數(shù)據(jù)和狀態(tài)源碼位置,是怎么實(shí)現(xiàn)的源碼位置是對(duì)的的初始化,它接受個(gè)參數(shù),為當(dāng)前實(shí)例,為的,為執(zhí)行的回調(diào)函數(shù),為當(dāng)前模塊的路徑。

20190221

請(qǐng)簡(jiǎn)述一下vuex實(shí)現(xiàn)原理

對(duì)vuex基礎(chǔ)概念有不懂的可以點(diǎn)這里

vuex實(shí)現(xiàn)原理我們簡(jiǎn)單過(guò)一遍源碼 地址 https://github.com/vuejs/vuex

首先我們例出幾個(gè)問(wèn)題進(jìn)行思考

store是怎么注冊(cè)的?

mutation,commit 是怎么實(shí)現(xiàn)的?

輔助函數(shù)是怎么實(shí)現(xiàn)的?

store是怎么注冊(cè)的

看了下面的源碼就很清楚了, 我們看到vuex在vue 的生命周期中的初始化鉤子前插入一段 Vuex 初始化代碼。給 Vue 的實(shí)例注入一個(gè) $store 的屬性,這也就是為什么我們?cè)?Vue 的組件中可以通過(guò) this.$store.xxx 訪問(wèn)到 Vuex 的各種數(shù)據(jù)和狀態(tài)

// 源碼位置 https://github.com/vuejs/vuex/blob/665455f8daf8512e7adbf63c2842bc0b1e39efdb/src/mixin.js

export default function (Vue) {
  const version = Number(Vue.version.split(".")[0])

  if (version >= 2) {
    Vue.mixin({ beforeCreate: vuexInit })
  } else {
    // override init and inject vuex init procedure
    // for 1.x backwards compatibility.
    const _init = Vue.prototype._init
    Vue.prototype._init = function (options = {}) {
      options.init = options.init
        ? [vuexInit].concat(options.init)
        : vuexInit
      _init.call(this, options)
    }
  }

  /**
   * Vuex init hook, injected into each instances init hooks list.
   */

  function vuexInit () {
    const options = this.$options
    // store injection
    if (options.store) {
      this.$store = typeof options.store === "function"
        ? options.store()
        : options.store
    } else if (options.parent && options.parent.$store) {
      this.$store = options.parent.$store
    }
  }
}
mutations,commit 是怎么實(shí)現(xiàn)的
// 源碼位置  https://github.com/vuejs/vuex/blob/665455f8daf8512e7adbf63c2842bc0b1e39efdb/src/store.js#L417
function registerMutation (store, type, handler, path = []) {
  const entry = store._mutations[type] || (store._mutations[type] = [])
  entry.push(function wrappedMutationHandler (payload) {
    handler(getNestedState(store.state, path), payload)
  })
}

registerMutation 是對(duì) store 的 mutation 的初始化,它接受 4 個(gè)參數(shù),store為當(dāng)前 Store 實(shí)例,type為 mutation 的 key,handler 為 mutation 執(zhí)行的回調(diào)函數(shù),path 為當(dāng)前模塊的路徑。mutation 的作用就是同步修改當(dāng)前模塊的 state ,函數(shù)首先通過(guò) type 拿到對(duì)應(yīng)的 mutation 對(duì)象數(shù)組, 然后把一個(gè) mutation 的包裝函數(shù) push 到這個(gè)數(shù)組中,這個(gè)函數(shù)接收一個(gè)參數(shù) payload,這個(gè)就是我們?cè)诙x mutation 的時(shí)候接收的額外參數(shù)。這個(gè)函數(shù)執(zhí)行的時(shí)候會(huì)調(diào)用 mutation 的回調(diào)函數(shù),并通過(guò) getNestedState(store.state, path) 方法得到當(dāng)前模塊的 state,和 playload 一起作為回調(diào)函數(shù)的參數(shù)

我們知道m(xù)utation是通過(guò)commit來(lái)觸發(fā)的,這里我們也來(lái)看一下commit的定義

// 源碼位置 https://github.com/vuejs/vuex/blob/665455f8daf8512e7adbf63c2842bc0b1e39efdb/src/store.js#L82

  commit (_type, _payload, _options) {
    // check object-style commit
    const {
      type,
      payload,
      options
    } = unifyObjectStyle(_type, _payload, _options)

    const mutation = { type, payload }
    const entry = this._mutations[type]
    if (!entry) {
      if (process.env.NODE_ENV !== "production") {
        console.error(`[vuex] unknown mutation type: ${type}`)
      }
      return
    }
    this._withCommit(() => {
      entry.forEach(function commitIterator (handler) {
        handler(payload)
      })
    })
    this._subscribers.forEach(sub => sub(mutation, this.state))

    if (
      process.env.NODE_ENV !== "production" &&
      options && options.silent
    ) {
      console.warn(
        `[vuex] mutation type: ${type}. Silent option has been removed. ` +
        "Use the filter functionality in the vue-devtools"
      )
    }
  }

commit 支持 3 個(gè)參數(shù),type 表示 mutation 的類型,payload 表示額外的參數(shù),根據(jù) type 去查找對(duì)應(yīng)的 mutation,如果找不到,則輸出一條錯(cuò)誤信息,否則遍歷這個(gè) type 對(duì)應(yīng)的 mutation 對(duì)象數(shù)組,執(zhí)行 handler(payload) 方法,這個(gè)方法就是之前定義的 wrappedMutationHandler(handler),執(zhí)行它就相當(dāng)于執(zhí)行了 registerMutation 注冊(cè)的回調(diào)函數(shù)

輔助函數(shù)

輔助函數(shù)的實(shí)現(xiàn)都差不太多,這里只講解mapState

// 源碼地址  https://github.com/vuejs/vuex/blob/665455f8daf8512e7adbf63c2842bc0b1e39efdb/src/helpers.js#L7

export const mapState = normalizeNamespace((namespace, states) => {
  const res = {}
  normalizeMap(states).forEach(({ key, val }) => {
    res[key] = function mappedState () {
      let state = this.$store.state
      let getters = this.$store.getters
      if (namespace) {
        const module = getModuleByNamespace(this.$store, "mapState", namespace)
        if (!module) {
          return
        }
        state = module.context.state
        getters = module.context.getters
      }
      return typeof val === "function"
        ? val.call(this, state, getters)
        : state[val]
    }
    // mark vuex getter for devtools
    res[key].vuex = true
  })
  return res
})

mapState在調(diào)用了 normalizeMap 函數(shù)后,把傳入的 states 轉(zhuǎn)換成由 {key, val} 對(duì)象構(gòu)成的數(shù)組,接著調(diào)用 forEach 方法遍歷這個(gè)數(shù)組,構(gòu)造一個(gè)新的對(duì)象,這個(gè)新對(duì)象每個(gè)元素都返回一個(gè)新的函數(shù) mappedState,函數(shù)對(duì) val 的類型判斷,如果 val 是一個(gè)函數(shù),則直接調(diào)用這個(gè) val 函數(shù),把當(dāng)前 store 上的 state 和 getters 作為參數(shù),返回值作為 mappedState 的返回值;否則直接把 this.$store.state[val] 作為 mappedState 的返回值

為了更直觀的理解,我們看下最終mapState的效果

  computed: mapState({
    name: state => state.name,
  })
  
  // 等同于
  
  computed: {
    name: this.$store.state.name
  }
關(guān)于JS每日一題

JS每日一題可以看成是一個(gè)語(yǔ)音答題社區(qū)
每天利用碎片時(shí)間采用60秒內(nèi)的語(yǔ)音形式來(lái)完成當(dāng)天的考題
群主在次日0點(diǎn)推送當(dāng)天的參考答案

注 絕不僅限于完成當(dāng)天任務(wù),更多是查漏補(bǔ)缺,學(xué)習(xí)群內(nèi)其它同學(xué)優(yōu)秀的答題思路

點(diǎn)擊加入答題

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/102015.html

相關(guān)文章

  • JS每日一題簡(jiǎn)述一下Vue.js的template編譯過(guò)程?

    摘要:?jiǎn)柡?jiǎn)述一下的編譯過(guò)程先上一張圖大致看一下整個(gè)流程從上圖中我們可以看到是從后開(kāi)始進(jìn)行中整體邏輯分為三個(gè)部分解析器將模板字符串轉(zhuǎn)換成優(yōu)化器對(duì)進(jìn)行靜態(tài)節(jié)點(diǎn)標(biāo)記,主要用來(lái)做虛擬的渲染優(yōu)化代碼生成器使用生成函數(shù)代碼字符串開(kāi)始前先解釋一下抽象 20190215問(wèn) 簡(jiǎn)述一下Vue.js的template編譯過(guò)程? 先上一張圖大致看一下整個(gè)流程showImg(https://image-static....

    NicolasHe 評(píng)論0 收藏0
  • JS每日一題:什么情況下適合使合vuex?Vuex使用中有幾個(gè)步驟?

    摘要:什么情況下適合使合使用中有幾個(gè)步驟開(kāi)始之前先簡(jiǎn)單了解一下定義是一個(gè)狀態(tài)管理機(jī)制采用集中式存儲(chǔ)應(yīng)用所有組件的狀態(tài)嗯,就是一句話能說(shuō)明白的,沒(méi)明白的,我們用代碼再理解一下什么叫集中式式存儲(chǔ)比如下面這段代碼,同時(shí)需要用到,那么我們首先能想到就是在 20190121 什么情況下適合使合vuex?Vuex使用中有幾個(gè)步驟? 開(kāi)始之前先簡(jiǎn)單了解一下vuex 定義: vuex是一個(gè)狀態(tài)管理機(jī)制,采用...

    wow_worktile 評(píng)論0 收藏0
  • 前端知識(shí)點(diǎn)(二)

    摘要:在給一個(gè)目標(biāo)對(duì)象為構(gòu)造函數(shù)的代理對(duì)象構(gòu)造實(shí)例時(shí)觸發(fā)該操作,比如在執(zhí)行時(shí)。 1、元素上下垂直居中的方式有哪些? 元素水平垂直居中的方式有哪些? absolute加margin方案 fixed 加 margin 方案 display:table 方案 行內(nèi)元素line-height方案 flex 彈性布局方案 transform 未知元素寬高解決方案 absolute加mar...

    zacklee 評(píng)論0 收藏0
  • 前端知識(shí)點(diǎn)(二)

    摘要:在給一個(gè)目標(biāo)對(duì)象為構(gòu)造函數(shù)的代理對(duì)象構(gòu)造實(shí)例時(shí)觸發(fā)該操作,比如在執(zhí)行時(shí)。 1、元素上下垂直居中的方式有哪些? 元素水平垂直居中的方式有哪些? absolute加margin方案 fixed 加 margin 方案 display:table 方案 行內(nèi)元素line-height方案 flex 彈性布局方案 transform 未知元素寬高解決方案 absolute加mar...

    lbool 評(píng)論0 收藏0
  • 前端知識(shí)點(diǎn)(二)

    摘要:在給一個(gè)目標(biāo)對(duì)象為構(gòu)造函數(shù)的代理對(duì)象構(gòu)造實(shí)例時(shí)觸發(fā)該操作,比如在執(zhí)行時(shí)。 1、元素上下垂直居中的方式有哪些? 元素水平垂直居中的方式有哪些? absolute加margin方案 fixed 加 margin 方案 display:table 方案 行內(nèi)元素line-height方案 flex 彈性布局方案 transform 未知元素寬高解決方案 absolute加mar...

    Alex 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<