VUEX源码解析

/plugins/devtool.js

  • 浏览器开发者工具支持监控VueX
const devtoolHook =
  typeof window !== 'undefined' &&
  window.__VUE_DEVTOOLS_GLOBAL_HOOK__

export default function devtoolPlugin (store) {
  if (!devtoolHook) return

  store._devtoolHook = devtoolHook

  devtoolHook.emit('vuex:init', store)

  devtoolHook.on('vuex:travel-to-state', targetState => {
    store.replaceState(targetState)
  })

  store.subscribe((mutation, state) => {
    devtoolHook.emit('vuex:mutation', mutation, state)
  })
}

/plugins/logger.js

  • repeat
function repeat (str, times) {
  return (new Array(times + 1)).join(str)
}

解析:字符串重复几次repeat('0', 5)会返回'00000'

  • pad
function pad (num, maxLength) {
  return repeat('0', maxLength - num.toString().length) + num;
}

解析:给数字补零,如pad(5, 5) 会返回'000005'

  • createLogger
    prev sate 代表之前的数据,mutations代表经过vuex中的mutations中方法修改后的数据,可以通过这个logger插件可以明细的看到数据的变化
import _ from 'lodash';
export function deepCopy (obj, cache = []) {
  // just return if obj is immutable value
  if (obj === null || typeof obj !== 'object') {
    return obj;
  }

  // if obj is hit, it is in circular structure
  const hit = _.find(cache, c => c.original === obj);
  if (hit) {
    return hit.copy;
  }

  const copy = Array.isArray(obj) ? [] : {};
  // put the copy into cache at first
  // because we want to refer it in recursive deepCopy
  cache.push({
    original: obj,
    copy
  });

  Object.keys(obj).forEach(key => {
    copy[key] = deepCopy(obj[key], cache);
  });

  return copy;
}

export default function createLogger ({
  collapsed = true,    // 自动展开记录的 mutation
  filter = (mutation, stateBefore, stateAfter) => true,
  transformer = state => state,  // 在开始记录之前转换状态
  mutationTransformer = mut => mut,  // mutation 按照 { type, payload } 格式记录
  logger = console    // 自定义 console 实现,默认为 `console`
} = {}) {
  return store => {
    let prevState = deepCopy(store.state)

    store.subscribe((mutation, state) => {
      if (typeof logger === 'undefined') {
        return
      }
      const nextState = deepCopy(state)

      if (filter(mutation, prevState, nextState)) {
        const time = new Date()
        const formattedTime = ` @ ${pad(time.getHours(), 2)}:${pad(time.getMinutes(), 2)}:${pad(time.getSeconds(), 2)}.${pad(time.getMilliseconds(), 3)}`
        const formattedMutation = mutationTransformer(mutation)
        const message = `mutation ${mutation.type}${formattedTime}`
        const startMessage = collapsed
          ? logger.groupCollapsed
          : logger.group

        // render
        try {
          startMessage.call(logger, message)
        } catch (e) {
          console.log(message)
        }

        logger.log('%c prev state', 'color: #9E9E9E; font-weight: bold', transformer(prevState))
        logger.log('%c mutation', 'color: #03A9F4; font-weight: bold', formattedMutation)
        logger.log('%c next state', 'color: #4CAF50; font-weight: bold', transformer(nextState))

        try {
          logger.groupEnd()
        } catch (e) {
          logger.log('—— log end ——')
        }
      }

      prevState = nextState
    })
  }
}
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 写在前面 因为对Vue.js很感兴趣,而且平时工作的技术栈也是Vue.js,这几个月花了些时间研究学习了一下Vue...
    染陌同学阅读 1,719评论 0 12
  • 前言 之前几篇解析 Vue 源码的文章都是完整的分析整个源码的执行过程,这篇文章我会将重点放在核心原理的解析,不会...
    心_c2a2阅读 1,568评论 1 8
  • 上一章总结了 Vuex 的框架原理,这一章我们将从 Vuex 的入口文件开始,分步骤阅读和解析源码。由于 Vuex...
    你的肖同学阅读 1,896评论 3 16
  • ## 框架和库的区别?> 框架(framework):一套完整的软件设计架构和**解决方案**。> > 库(lib...
    Rui_bdad阅读 3,158评论 1 4
  • “妈妈坐在门前,哼着花儿与少年虽已时隔多年,记得她泪水涟涟那些幽暗的时光,那些坚持与慌张在临别的门前,妈妈望着我说...
    飞飞的碎碎念阅读 1,044评论 6 23

友情链接更多精彩内容