diff --git a/packages/uni-mp-compiler/src/template/codegen.ts b/packages/uni-mp-compiler/src/template/codegen.ts index a9f2aa6323389f4376f1303db4c802db004c9763..9a7ed1ec565c48eaaf9c982caaff373590995166 100644 --- a/packages/uni-mp-compiler/src/template/codegen.ts +++ b/packages/uni-mp-compiler/src/template/codegen.ts @@ -1,8 +1,11 @@ import { hyphenate } from '@vue/shared' import { SLOT_DEFAULT_NAME, dynamicSlotName } from '@dcloudio/uni-shared' import { + createBindDirectiveNode, formatMiniProgramEvent, + isDirectiveNode, isElementNode, + isSimpleExpressionNode, isUserComponent, MiniProgramCompilerOptions, } from '@dcloudio/uni-cli-shared' @@ -251,6 +254,29 @@ function genComponent(node: ComponentNode, context: TemplateCodegenContext) { return genElement(node, context) } +function genEventHandlerAttr(type: string) { + return `data-e-` + type +} + +function addEventHandlers({ props }: ElementNode) { + props.forEach((prop) => { + if (!isDirectiveNode(prop)) { + return + } + const { name, arg, exp } = prop + if (name !== 'on' || !arg || !exp) { + return + } + if (!isSimpleExpressionNode(arg) || !isSimpleExpressionNode(exp)) { + return + } + // TODO 目前硬编码,仅限ready + if (arg.content === 'ready') { + props.push(createBindDirectiveNode(genEventHandlerAttr(arg.content), exp)) + } + }) +} + function isLazyElement(node: ElementNode, context: TemplateCodegenContext) { if (!context.lazyElement) { return false @@ -278,6 +304,10 @@ function isLazyElement(node: ElementNode, context: TemplateCodegenContext) { */ function genLazyElement(node: ElementNode, context: TemplateCodegenContext) { const { push } = context + // TODO 目前硬编码,仅限 editor 的 ready + if (node.tag === 'editor') { + addEventHandlers(node) + } if (!isIfElementNode(node)) { push(` ready 首次渲染 diff --git a/packages/uni-mp-vue/src/helpers/vOn.ts b/packages/uni-mp-vue/src/helpers/vOn.ts index ee63b99b0b51707a262dda420ca5c37fc4f23b40..fb97e3292dd1010eaa17b42b236c0c8660f04573 100644 --- a/packages/uni-mp-vue/src/helpers/vOn.ts +++ b/packages/uni-mp-vue/src/helpers/vOn.ts @@ -17,6 +17,7 @@ type EventValue = Function | Function[] interface Invoker { (evt: MPEvent): unknown + id: string value: EventValue } @@ -49,8 +50,10 @@ export function vOn(value: EventValue | undefined, key?: number | string) { } else { // add mpInstance[name] = createInvoker( + name, value, - instance as unknown as ComponentInternalInstance + instance as unknown as ComponentInternalInstance, + mpInstance ) } return name @@ -65,15 +68,26 @@ export interface MPEvent extends WechatMiniprogram.BaseEvent { stopImmediatePropagation: () => void } +const editorReady = 'eReady' + function createInvoker( + name: string, initialValue: EventValue, - instance: ComponentInternalInstance | null + instance: ComponentInternalInstance | null, + mpInstance: Record ) { const invoker: Invoker = (e: MPEvent) => { + const dataset = e.target && e.target.dataset + // TODO 临时解决 editor ready 事件可能错乱的问题 https://github.com/dcloudio/uni-app/issues/3406 + if (mpInstance && dataset && dataset[editorReady]) { + if (invoker.id !== dataset[editorReady]) { + return mpInstance[dataset[editorReady]](e) + } + } patchMPEvent(e) let args: unknown[] = [e] - if ((e as MPEvent).detail && (e as MPEvent).detail.__args__) { - args = (e as MPEvent).detail.__args__! + if (e.detail && e.detail.__args__) { + args = e.detail.__args__! } const eventValue = invoker.value const invoke = () => @@ -85,18 +99,14 @@ function createInvoker( ) // 冒泡事件触发时,启用延迟策略,避免同一批次的事件执行时机不正确,对性能可能有略微影响 https://github.com/dcloudio/uni-app/issues/3228 - const eventTarget = (e as MPEvent).target - const eventSync = eventTarget - ? eventTarget.dataset - ? eventTarget.dataset.eventsync === 'true' - : false - : false + const eventSync = dataset && dataset.eventsync if (bubbles.includes(e.type) && !eventSync) { setTimeout(invoke) } else { return invoke() } } + invoker.id = name invoker.value = initialValue return invoker } diff --git a/packages/uni-mp-weixin/__tests__/component.spec.ts b/packages/uni-mp-weixin/__tests__/component.spec.ts index 738120eaa3fdfce2691af90e053003832554c692..233a1c70d24969e51430f19898749ae1fd2a5122 100644 --- a/packages/uni-mp-weixin/__tests__/component.spec.ts +++ b/packages/uni-mp-weixin/__tests__/component.spec.ts @@ -60,21 +60,21 @@ describe('mp-weixin: transform component', () => { ) assert( ``, - ``, + ``, `(_ctx, _cache) => { return { a: _o(_ctx.ready) } }` ) assert( ``, - ``, + ``, `(_ctx, _cache) => { return _e({ a: _ctx.ok1 }, _ctx.ok1 ? { b: _o(_ctx.ready) } : _ctx.ok2 ? {} : {}, { c: _ctx.ok2 }) }` ) assert( ``, - ``, + ``, `(_ctx, _cache) => { return _e({ a: _ctx.ok1 }, _ctx.ok1 ? { b: _o(_ctx.ready) } : _ctx.ok2 ? {} : { d: _o(_ctx.ready) }, { c: _ctx.ok2 }) }`