提交 174b8325 编写于 作者: fxy060608's avatar fxy060608

fix(mp-weixin): edge case of editor ready (#3406)

上级 f11e6834
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(`<block`)
// r0 => ready 首次渲染
......
......@@ -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<string, any>
) {
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
}
......
......@@ -60,21 +60,21 @@ describe('mp-weixin: transform component', () => {
)
assert(
`<editor @ready="ready"/>`,
`<block wx:if="{{r0}}"><editor bindready="{{a}}"/></block>`,
`<block wx:if="{{r0}}"><editor bindready="{{a}}" data-e-ready="{{a}}"/></block>`,
`(_ctx, _cache) => {
return { a: _o(_ctx.ready) }
}`
)
assert(
`<editor v-if="ok1" @ready="ready"/><editor v-else-if="ok2"/><editor v-else/>`,
`<editor wx:if="{{a}}" bindready="{{b}}"/><editor wx:elif="{{c}}"/><editor wx:else/>`,
`<editor wx:if="{{a}}" bindready="{{b}}" data-e-ready="{{b}}"/><editor wx:elif="{{c}}"/><editor wx:else/>`,
`(_ctx, _cache) => {
return _e({ a: _ctx.ok1 }, _ctx.ok1 ? { b: _o(_ctx.ready) } : _ctx.ok2 ? {} : {}, { c: _ctx.ok2 })
}`
)
assert(
`<editor v-if="ok1" @ready="ready"/><editor v-else-if="ok2"/><editor v-else @ready="ready"/>`,
`<editor wx:if="{{a}}" bindready="{{b}}"/><editor wx:elif="{{c}}"/><block wx:else><editor wx:if="{{r0}}" bindready="{{d}}"/></block>`,
`<editor wx:if="{{a}}" bindready="{{b}}" data-e-ready="{{b}}"/><editor wx:elif="{{c}}"/><block wx:else><editor wx:if="{{r0}}" bindready="{{d}}" data-e-ready="{{d}}"/></block>`,
`(_ctx, _cache) => {
return _e({ a: _ctx.ok1 }, _ctx.ok1 ? { b: _o(_ctx.ready) } : _ctx.ok2 ? {} : { d: _o(_ctx.ready) }, { c: _ctx.ok2 })
}`
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册