Skip to content

Logger 插件

js
/**
 * logger日志插件
  import createLogger from 'vuex/dist/logger’
  const store = new Vuex.Store({
    plugins: [createLogger()]
  })

 * @author guzhanghua
 * @export
 * @param {*} [{
 *     collapsed = true,
 *     filter = (mutation, stateBefore, stateAfter) => true,
 *     transformer = state => state,
 *     mutationTransformer = mut => mut,
 *     logger = console
 * }={}]
 * @returns
 */
export default function createLogger({
  collapsed = true,
  filter = (mutation, stateBefore, stateAfter) => true,
  transformer = state => state,
  mutationTransformer = mut => mut,
  logger = console,
} = {}) {
  return store => {
    // 保存上一的 state数据
    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
    })
  }
}

解析

对于 logger 插件其核心就是使用了 store.subscribe(() => {}) 订阅了 Vuex 的 mutation 方法,那么在每一次执行 mutaion 的时候就会首先回调整个 store._subscribers数组对象,从而检测到每次数据的改变过程