Vue source code Vuex (4) plugin
学习内容和文章内容来自 黄轶老师
"Vue.js2.0 Source Code Demystification" ,
"Vue.js 3.0 Core Source Code Analysis"
这里分析的源码是Runtime + Compiler 的 Vue.js
调试代码在:node_modules\vue\dist\vue.esm.js 里添加
vue版本:Vue.js 2.5.17-beta
你越是认真生活,你的生活就会越美好!
Vue source code learning complete directory
plug-in
In addition to the access capabilities provided by Vuex, it also provides a plug-in capability that allows us to store
monitor change process of to do something.
Vuex's store
Accept plugins
option, we can pass in plugins when Store
instantiating , which is an array, and then Store
when executing the constructor, these plugins will be executed:
const {
plugins = [],
strict = false
} = options
// apply plugins
plugins.forEach(plugin => plugin(this))
In our actual projects, what we use the most is the built-in Logger
plugin , which can help us track state
changes and output some formatted logs.
Let's analyze the implementation of this plug-in.
Logger
plug-in
Logger
The plugin is defined src/plugins/logger.js
in :
export default function createLogger ({
collapsed = true,
filter = (mutation, stateBefore, stateAfter) => true,
transformer = state => state,
mutationTransformer = mut => mut,
logger = 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
})
}
}
function repeat (str, times) {
return (new Array(times + 1)).join(str)
}
function pad (num, maxLength) {
return repeat('0', maxLength - num.toString().length) + num
}
The parameter received by the plug-in function is store
an instance , which executes store.subscribe
the method. First, let's look at the definition subscribe
of :
subscribe (fn) {
return genericSubscribe(fn, this._subscribers)
}
function genericSubscribe (fn, subs) {
if (subs.indexOf(fn) < 0) {
subs.push(fn)
}
return () => {
const i = subs.indexOf(fn)
if (i > -1) {
subs.splice(i, 1)
}
}
}
subscribe
The logic of is very simple, that is, add a function this._subscribers
to and return a unsubscribe
method.
And when we store.commit
execute the method, we will traverse this._subscribers
and execute their corresponding callback functions:
commit (_type, _payload, _options) {
const {
type,
payload,
options
} = unifyObjectStyle(_type, _payload, _options)
const mutation = {
type, payload }
// ...
this._subscribers.forEach(sub => sub(mutation, this.state))
}
Going back to our Logger
function , it is equivalent to subscribing mutation
to the commit. Its prevState
means the previous one state
and the one afternextState
the commit . Both of them need to execute the method to copy a copy of the object, so that their modifications will not affect the original .mutation
state
state
deepCopy
store.state
Next, construct some formatted messages, print out some time messages message
, the previous state prevState
, the corresponding mutation
operation formattedMutation
and the next state nextState
.
Final update to prepare prevState = nextState
for the next commit mutation
output log.
Summarize
So far, the plug-in analysis of Vuex is over. Vuex supports plug-ins by design, allowing us to track store
internal . Logger
Plug-ins also provide good guidance during our development stage.
Of course, we can also Vuex
implement plug-ins to help us achieve some specific requirements.
Vue source code learning directory
Vue source code learning complete directory
谢谢你阅读到了最后~
期待你关注、收藏、评论、点赞~
让我们一起 变得更强