Directive System Source Code
Directive Registration and Parsing
Directive Registration Process:
// Global directive registration
app.directive('focus', {
mounted(el) {
el.focus()
}
})
// Core logic in source code
function registerDirective(app, name, directive) {
app._context.directives[name] = directive
}
// Local directive registration
const componentDirectives = {
'custom': {
beforeMount(el, binding) {
// ...
}
}
}
Directive Parsing Process:
- Identify directive syntax during template compilation
- Create directive node descriptor object
- Associate directive with component instance
Directive Binding and Update Process
Directive Lifecycle Execution Order:
beforeMount → mounted → beforeUpdate → updated → beforeUnmount → unmounted
Key Source Code Implementation Points:
// Core directive binding logic
function mountDirective(vnode, directive) {
const { instance, value, oldValue } = vnode
const { beforeMount, mounted } = directive
if (beforeMount) {
callWithAsyncErrorHandling(beforeMount, instance, ErrorCodes.DIRECTIVE_HOOK, [el, binding])
}
if (mounted) {
callWithAsyncErrorHandling(mounted, instance, ErrorCodes.DIRECTIVE_HOOK, [el, binding])
}
}
// Directive update logic
function updateDirective(vnode, oldVNode) {
const { instance, value, oldValue } = vnode
const { beforeUpdate, updated } = directive
if (beforeUpdate) {
callWithAsyncErrorHandling(beforeUpdate, instance, ErrorCodes.DIRECTIVE_HOOK, [el, binding])
}
// Execute update operations...
if (updated) {
callWithAsyncErrorHandling(updated, instance, ErrorCodes.DIRECTIVE_HOOK, [el, binding])
}
}
Custom Directive Internal Implementation
Complete Custom Directive Example:
const vDebounce = {
mounted(el, binding) {
const { value: fn, arg: delay = 300 } = binding
let timeout
el.addEventListener('input', () => {
clearTimeout(timeout)
timeout = setTimeout(() => fn(), delay)
})
},
unmounted(el) {
el.removeEventListener('input')
}
}
// Source-level implementation principle
function createDirective() {
return {
beforeMount: (el, binding) => { /* Initialization logic */ },
mounted: (el, binding) => { /* First mount logic */ },
beforeUpdate: (el, binding) => { /* Pre-update logic */ },
updated: (el, binding) => { /* Post-update logic */ },
beforeUnmount: (el, binding) => { /* Pre-unmount cleanup */ },
unmounted: (el, binding) => { /* Complete unmount logic */ }
}
}
Directive Performance Optimization
Optimization Strategies:
- Directive Merging: Consolidate multiple calls to the same directive
- Lazy Execution: Delay non-critical directive execution
- Caching Mechanism: Cache directive computation results
Performance Optimization Example:
const vMemo = {
mounted(el, binding) {
const { value, arg: key } = binding
if (!el._memoCache) el._memoCache = new Map()
if (el._memoCache.has(key) && el._memoCache.get(key) === value) return
el._memoCache.set(key, value)
// Execute actual directive logic...
},
updated(el, binding) {
// Similar caching check logic as mounted
}
}
Directive Security and Compatibility
Security Measures:
- DOM Operation Sanitization: Automatically filter dangerous attributes
- Event Handler Validation: Verify event listener legitimacy
- XSS Protection: Automatically escape dynamic content
Compatibility Handling Example:
const vIntersection = {
mounted(el, binding) {
if ('IntersectionObserver' in window) {
// Modern browser implementation
} else {
// Fallback: Scroll event polling
const fallback = () => {
const rect = el.getBoundingClientRect()
if (rect.top < window.innerHeight) {
binding.value()
window.removeEventListener('scroll', fallback)
}
}
window.addEventListener('scroll', fallback)
}
}
}
Event System Source Code
Event Binding Internal Implementation
v-on Directive Source Code Process:
- Parse event syntax during template compilation
- Create wrapper function for event listener
- Bind event during component mounting
Simplified Implementation:
function processEvent(el, event, modifiers, handler) {
const wrappedHandler = (e) => {
// Handle modifier logic
if (modifiers.stop) e.stopPropagation()
if (modifiers.prevent) e.preventDefault()
// Execute original handler
handler.call(this, e)
}
el.addEventListener(event, wrappedHandler)
}
Event Modifier Handling Logic
Common Modifier Implementations:
const modifierHandlers = {
stop(e) { e.stopPropagation() },
prevent(e) { e.preventDefault() },
self(e) { return e.target === e.currentTarget },
once(fn) {
let called = false
return function(...args) {
if (!called) {
called = true
fn.apply(this, args)
}
}
}
}
// Handle modifier combinations
function applyModifiers(handler, modifiers) {
return modifiers.reduce((fn, modifier) => {
return modifierHandlers[modifier]
? modifierHandlers[modifier](fn)
: fn
}, handler)
}
Event Bubbling and Capturing Implementation
Event Phase Control:
function addEventListener(el, event, handler, options) {
const { capture, passive } = options
el.addEventListener(event, handler, {
capture,
passive
})
}
// Apply in directive processing
function processEvent(el, event, modifiers, handler) {
const options = {
capture: modifiers.capture,
passive: modifiers.passive
}
addEventListener(el, event, handler, options)
}
Custom Event Triggering and Listening
Custom Event System:
// Trigger custom event
function emit(instance, eventName, ...args) {
const events = instance.vnode.props?.[`on${capitalize(eventName)}`]
if (events) {
events(...args)
}
}
// Listen to custom event
function on(component, eventName, callback) {
component._events = component._events || {}
component._events[eventName] = component._events[eventName] || []
component._events[eventName].push(callback)
}
Event System Performance Optimization
Optimization Strategies:
- Event Delegation: Handle events at the parent element
- Throttling and Debouncing: Control event trigger frequency
- Passive Listening: Optimize scroll performance
Event Delegation Example:
function delegateEvents(events) {
const eventMap = {}
events.forEach(({ event, selector, handler }) => {
if (!eventMap[event]) {
eventMap[event] = []
document.addEventListener(event, dispatchEvent)
}
eventMap[event].push({ selector, handler })
})
}
function dispatchEvent(e) {
const handlers = eventMap[e.type]
handlers.forEach(({ selector, handler }) => {
if (e.target.matches(selector)) {
handler(e)
}
})
}
State Management Source Code (Vuex)
Vuex Core Modules
Vuex Core Structure:
const store = {
state: reactive({}),
_mutations: {},
_actions: {},
_getters: {},
commit(type, payload) {
this._mutations[type].forEach(fn => fn(payload))
},
dispatch(type, payload) {
return this._actions[type].forEach(fn => fn(payload))
}
}
Modular Implementation:
function registerModule(store, path, module) {
const namespace = getNamespace(path)
module.namespaced = true
// Register state
store._modulesNamespaceMap[namespace] = module
// Register mutations/actions/getters
installModule(store, rootState, path, module)
}
Plugins and Helper Functions Implementation
Plugin System:
function use(plugin) {
plugin(this)
}
// Plugin example
const myPlugin = (store) => {
store.subscribe((mutation, state) => {
console.log(mutation.type, mutation.payload)
})
}
Helper Function Source Code:
function mapState(namespace, states) {
const res = {}
normalizeMap(states).forEach(({ key, val }) => {
res[key] = function mappedState() {
return typeof val === 'function'
? val.call(this, this.$store.state, this.$store.getters)
: this.$store.state[namespace][val]
}
})
return res
}
State Persistence and Debugging Tools
State Persistence Implementation:
function createPersistedState() {
return (store) => {
// Load from storage on initialization
const savedState = localStorage.getItem('vuex')
if (savedState) {
store.replaceState(JSON.parse(savedState))
}
// Subscribe to mutation changes
store.subscribe((mutation, state) => {
localStorage.setItem('vuex', JSON.stringify(state))
})
}
}
Debugging Tool Integration:
function devtoolPlugin(store) {
if (!devtools) return
devtools.on('vuex:travel-to-state', targetState => {
store.replaceState(targetState)
})
store.subscribe((mutation, state) => {
devtools.emit('vuex:mutation', mutation, state)
})
}
Vuex Modular Design
Dynamic Module Registration:
function registerModule(store, path, rawModule) {
const namespace = getNamespace(path)
// Create submodule
const module = {
_raw: rawModule,
_children: {},
state: rawModule.state
}
// Recursively register submodules
if (rawModule.modules) {
forEachValue(rawModule.modules, (child, key) => {
registerModule(store, path.concat(key), child)
})
}
// Install module
installModule(store, state, path, module)
}
Vuex Performance Optimization
Optimization Strategies:
- Strict Mode Control: Disable strict checks in production
- Batch Updates: Combine multiple mutations
- Lazy Module Loading: Dynamically register modules
Performance Optimization Example:
function enableStrictMode(store) {
if (process.env.NODE_ENV !== 'production') {
store._vm.$watch(
() => store._data,
() => {
assert(store._committing, `do not mutate vuex store outside mutation handlers`)
},
{ deep: true, sync: true }
)
}
}
Security Strategies:
- Type Checking: Validate mutation/action types
- Input Sanitization: Filter user input data
- Access Control: Module namespace isolation
By deeply analyzing the source code of Vue 3’s core features, developers can gain a thorough understanding of the framework’s inner workings, enabling better design decisions and targeted optimizations for specific scenarios. This foundational knowledge is critical for building high-performance, maintainable large-scale Vue applications.



