Refactor event handler setup: improve arrow function and function call handling, enhance error logging
This commit is contained in:
parent
c44c9fc2c0
commit
e9ddbcdf47
136
src/main.ts
136
src/main.ts
|
@ -269,8 +269,8 @@ export default (options: ComponentOptions) => {
|
||||||
// Handle arrow function: @click="e => setState('count', count + 1)"
|
// Handle arrow function: @click="e => setState('count', count + 1)"
|
||||||
this._setupArrowFunctionHandler(element, eventName, handlerValue)
|
this._setupArrowFunctionHandler(element, eventName, handlerValue)
|
||||||
} else if (handlerValue.includes('(') && handlerValue.includes(')')) {
|
} else if (handlerValue.includes('(') && handlerValue.includes(')')) {
|
||||||
// Handle function call: @click="increment(5)"
|
// Handle function call: @click="increment(5)"
|
||||||
this._setupFunctionCallHandler(element, eventName, handlerValue)
|
this._setupFunctionCallHandler(element, eventName, handlerValue)
|
||||||
} else if (typeof (this as any)[handlerValue] === 'function') {
|
} else if (typeof (this as any)[handlerValue] === 'function') {
|
||||||
// Handle method reference: @click="handleClick"
|
// Handle method reference: @click="handleClick"
|
||||||
element.addEventListener(eventName, (this as any)[handlerValue].bind(this))
|
element.addEventListener(eventName, (this as any)[handlerValue].bind(this))
|
||||||
|
@ -287,56 +287,56 @@ export default (options: ComponentOptions) => {
|
||||||
this._textBindings = textBindings
|
this._textBindings = textBindings
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle arrow function
|
// Handle arrow function
|
||||||
private _setupArrowFunctionHandler(element: Element, eventName: string, handlerValue: string) {
|
private _setupArrowFunctionHandler(element: Element, eventName: string, handlerValue: string) {
|
||||||
element.addEventListener(eventName, (event: Event) => {
|
element.addEventListener(eventName, (event: Event) => {
|
||||||
try {
|
try {
|
||||||
// Arrow function parsing
|
// Arrow function parsing
|
||||||
const arrowIndex = handlerValue.indexOf('=>')
|
const arrowIndex = handlerValue.indexOf('=>')
|
||||||
const paramsStr = handlerValue.substring(0, arrowIndex).trim()
|
const paramsStr = handlerValue.substring(0, arrowIndex).trim()
|
||||||
let bodyStr = handlerValue.substring(arrowIndex + 2).trim()
|
let bodyStr = handlerValue.substring(arrowIndex + 2).trim()
|
||||||
|
|
||||||
// Check if the function body is wrapped in {}
|
// Check if the function body is wrapped in {}
|
||||||
const isMultiline = bodyStr.startsWith('{') && bodyStr.endsWith('}')
|
const isMultiline = bodyStr.startsWith('{') && bodyStr.endsWith('}')
|
||||||
|
|
||||||
// If it is a multiline function body, remove the outer braces
|
// If it is a multiline function body, remove the outer braces
|
||||||
if (isMultiline) {
|
if (isMultiline) {
|
||||||
// Remove the outer braces
|
// Remove the outer braces
|
||||||
bodyStr = bodyStr.substring(1, bodyStr.length - 1)
|
bodyStr = bodyStr.substring(1, bodyStr.length - 1)
|
||||||
|
|
||||||
// Build code for multiline arrow function
|
// Build code for multiline arrow function
|
||||||
const functionCode = `
|
const functionCode = `
|
||||||
return function(${paramsStr}) {
|
return function(${paramsStr}) {
|
||||||
${bodyStr}
|
${bodyStr}
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
// Create context object
|
// Create context object
|
||||||
const context = this._createHandlerContext(event, element)
|
const context = this._createHandlerContext(event, element)
|
||||||
|
|
||||||
// Create and call function
|
// Create and call function
|
||||||
const handlerFn = new Function(functionCode).call(null)
|
const handlerFn = new Function(functionCode).call(null)
|
||||||
handlerFn.apply(context, [event])
|
handlerFn.apply(context, [event])
|
||||||
} else {
|
} else {
|
||||||
// Single line arrow function, directly return expression result
|
// Single line arrow function, directly return expression result
|
||||||
const functionCode = `
|
const functionCode = `
|
||||||
return function(${paramsStr}) {
|
return function(${paramsStr}) {
|
||||||
return ${bodyStr}
|
return ${bodyStr}
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
// Create context object
|
// Create context object
|
||||||
const context = this._createHandlerContext(event, element)
|
const context = this._createHandlerContext(event, element)
|
||||||
|
|
||||||
// Create and call function
|
// Create and call function
|
||||||
const handlerFn = new Function(functionCode).call(null)
|
const handlerFn = new Function(functionCode).call(null)
|
||||||
handlerFn.apply(context, [event])
|
handlerFn.apply(context, [event])
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(`Error executing arrow function handler: ${handlerValue}`, err)
|
console.error(`Error executing arrow function handler: ${handlerValue}`, err)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create handler context
|
// Create handler context
|
||||||
private _createHandlerContext(event: Event, element: Element) {
|
private _createHandlerContext(event: Event, element: Element) {
|
||||||
|
@ -367,51 +367,51 @@ export default (options: ComponentOptions) => {
|
||||||
return context
|
return context
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle function call, such as @click="increment(5)"
|
// Handle function call, such as @click="increment(5)"
|
||||||
private _setupFunctionCallHandler(element: Element, eventName: string, handlerValue: string) {
|
private _setupFunctionCallHandler(element: Element, eventName: string, handlerValue: string) {
|
||||||
element.addEventListener(eventName, (event: Event) => {
|
element.addEventListener(eventName, (event: Event) => {
|
||||||
try {
|
try {
|
||||||
// Create context object
|
// Create context object
|
||||||
const context = this._createHandlerContext(event, element)
|
const context = this._createHandlerContext(event, element)
|
||||||
|
|
||||||
// Create and execute function call
|
// Create and execute function call
|
||||||
const fnStr = `
|
const fnStr = `
|
||||||
with(this) {
|
with(this) {
|
||||||
${handlerValue}
|
${handlerValue}
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
new Function(fnStr).call(context)
|
new Function(fnStr).call(context)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(`Error executing function call handler: ${handlerValue}`, err)
|
console.error(`Error executing function call handler: ${handlerValue}`, err)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle simple expression, such as @click="count++" or @input="name = $event.target.value"
|
// Handle simple expression, such as @click="count++" or @input="name = $event.target.value"
|
||||||
private _setupExpressionHandler(element: Element, eventName: string, handlerValue: string) {
|
private _setupExpressionHandler(element: Element, eventName: string, handlerValue: string) {
|
||||||
element.addEventListener(eventName, (event: Event) => {
|
element.addEventListener(eventName, (event: Event) => {
|
||||||
try {
|
try {
|
||||||
// Create context object
|
// Create context object
|
||||||
const context = this._createHandlerContext(event, element)
|
const context = this._createHandlerContext(event, element)
|
||||||
|
|
||||||
// Create expression function
|
// Create expression function
|
||||||
const fnStr = `
|
const fnStr = `
|
||||||
with(this) {
|
with(this) {
|
||||||
${handlerValue}
|
${handlerValue}
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
// Execute expression
|
// Execute expression
|
||||||
const result = new Function(fnStr).call(context)
|
const result = new Function(fnStr).call(context)
|
||||||
|
|
||||||
// If the expression returns a value, it can be used for two-way binding
|
// If the expression returns a value, it can be used for two-way binding
|
||||||
return result
|
return result
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(`Error executing expression handler: ${handlerValue}`, err)
|
console.error(`Error executing expression handler: ${handlerValue}`, err)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update text node
|
// Update text node
|
||||||
private _updateTextNode(node: Text, expr: string, template: string) {
|
private _updateTextNode(node: Text, expr: string, template: string) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user