diff --git a/packages/uni-app-plus/dist/uni-app-view.umd.js b/packages/uni-app-plus/dist/uni-app-view.umd.js index 583cf06b8885097601ac0e222ec9b9c1d70d9232..cd58be1ee52e11f18df5af714520a9f7e375960d 100644 --- a/packages/uni-app-plus/dist/uni-app-view.umd.js +++ b/packages/uni-app-plus/dist/uni-app-view.umd.js @@ -881,6 +881,7 @@ var ATTR_TEXT_CONTENT = "textContent"; var ATTR_V_SHOW = ".vShow"; var ATTR_V_OWNER_ID = ".vOwnerId"; + var ATTR_V_RENDERJS = ".vRenderjs"; var ATTR_CHANGE_PREFIX = "change:"; var ACTION_TYPE_PAGE_CREATE = 1; var ACTION_TYPE_PAGE_CREATED = 2; @@ -7633,45 +7634,53 @@ }); return res; } + function createActionJob(fn, priority) { + return fn.priority = priority, fn; + } var postActionJobs = new Set(); - function queuePostActionJob(job) { - postActionJobs.add(job); + var JOB_PRIORITY_UPDATE = 1; + var JOB_PRIORITY_REBUILD = 2; + var JOB_PRIORITY_RENDERJS = 3; + var JOB_PRIORITY_WXS_PROPS = 4; + function queuePostActionJob(job, priority) { + postActionJobs.add(createActionJob(job, priority)); } function flushPostActionJobs() { { console.log(formatLog("flushPostActionJobs", postActionJobs.size)); } try { - postActionJobs.forEach((fn) => fn()); + ; + [...postActionJobs].sort((a2, b) => a2.priority - b.priority).forEach((fn) => fn()); } finally { postActionJobs.clear(); } } - function getWxsModule(moduleId) { + function getViewModule(moduleId, ownerEl) { var __wxsModules = window["__" + WXS_MODULES]; - var __renderjsModules = window["__" + RENDERJS_MODULES]; var module = __wxsModules && __wxsModules[moduleId]; - if (!module) { - module = __renderjsModules && __renderjsModules[moduleId]; + if (module) { + return module; } - if (!module) { - return console.error(formatLog("wxs or renderjs", moduleId + " not found")); + if (ownerEl && ownerEl.__renderjsInstances) { + return ownerEl.__renderjsInstances[moduleId]; } - return module; } var WXS_PROTOCOL_LEN = WXS_PROTOCOL.length; - function invokeWxs(wxsStr, invokerArgs) { - var [, moduleId, invoker, args] = JSON.parse(wxsStr.substr(WXS_PROTOCOL_LEN)); + function invokeWxs(el, wxsStr, invokerArgs) { + var [ownerId, moduleId, invoker, args] = parseWxs(wxsStr); + var ownerEl = resolveOwnerEl(el, ownerId); if (isArray(invokerArgs) || isArray(args)) { var [moduleName, mehtodName] = invoker.split("."); - return invokeWxsMethod(moduleId, moduleName, mehtodName, invokerArgs || args); + return invokeWxsMethod(ownerEl, moduleId, moduleName, mehtodName, invokerArgs || args); } - return getWxsProp(moduleId, invoker); + return getWxsProp(ownerEl, moduleId, invoker); } - function invokeWxsEvent(wxsStr, el, event) { - var [ownerId, moduleId, invoker] = JSON.parse(wxsStr.substr(WXS_PROTOCOL_LEN)); + function invokeWxsEvent(el, wxsStr, event) { + var [ownerId, moduleId, invoker] = parseWxs(wxsStr); var [moduleName, mehtodName] = invoker.split("."); - return invokeWxsMethod(moduleId, moduleName, mehtodName, [wrapperWxsEvent(event, el), getComponentDescriptor(createComponentDescriptorVm(resolveOwnerEl(el, ownerId)), false)]); + var ownerEl = resolveOwnerEl(el, ownerId); + return invokeWxsMethod(ownerEl, moduleId, moduleName, mehtodName, [wrapperWxsEvent(event, el), getComponentDescriptor(createComponentDescriptorVm(ownerEl), false)]); } function resolveOwnerEl(el, ownerId) { if (el.__ownerId === ownerId) { @@ -7686,13 +7695,17 @@ } return el; } + function parseWxs(wxsStr) { + return JSON.parse(wxsStr.substr(WXS_PROTOCOL_LEN)); + } function invokeWxsProps(wxsStr, el, newValue, oldValue) { - var [ownerId, moduleId, invoker] = JSON.parse(wxsStr.substr(WXS_PROTOCOL_LEN)); + var [ownerId, moduleId, invoker] = parseWxs(wxsStr); + var ownerEl = resolveOwnerEl(el, ownerId); var [moduleName, mehtodName] = invoker.split("."); - return invokeWxsMethod(moduleId, moduleName, mehtodName, [newValue, oldValue, getComponentDescriptor(createComponentDescriptorVm(resolveOwnerEl(el, ownerId)), false), getComponentDescriptor(createComponentDescriptorVm(el), false)]); + return invokeWxsMethod(ownerEl, moduleId, moduleName, mehtodName, [newValue, oldValue, getComponentDescriptor(createComponentDescriptorVm(ownerEl), false), getComponentDescriptor(createComponentDescriptorVm(el), false)]); } - function invokeWxsMethod(moduleId, moduleName, methodName, args) { - var module = getWxsModule(moduleId); + function invokeWxsMethod(ownerEl, moduleId, moduleName, methodName, args) { + var module = getViewModule(moduleId, ownerEl); if (!module) { return console.error(formatLog("wxs", "module " + moduleName + " not found")); } @@ -7702,8 +7715,8 @@ } return method.apply(module, args); } - function getWxsProp(moduleId, dataPath) { - var module = getWxsModule(moduleId); + function getWxsProp(ownerEl, moduleId, dataPath) { + var module = getViewModule(moduleId, ownerEl); if (!module) { return console.error(formatLog("wxs", "module " + dataPath + " not found")); } @@ -7771,6 +7784,44 @@ } }); } + function initRenderjs(node, moduleIds) { + Object.keys(moduleIds).forEach((name) => { + initRenderjsModule(node, moduleIds[name]); + }); + } + function destroyRenderjs(node) { + var { + __renderjsInstances + } = node.$; + if (!__renderjsInstances) { + return; + } + Object.keys(__renderjsInstances).forEach((id2) => { + __renderjsInstances[id2].$.appContext.app.unmount(); + }); + } + function initRenderjsModule(node, moduleId) { + var options = getRenderjsModule(moduleId); + if (!options) { + return; + } + var el = node.$; + (el.__renderjsInstances || (el.__renderjsInstances = {}))[moduleId] = createRenderjsInstance(options); + } + function getRenderjsModule(moduleId) { + var __renderjsModules = window["__" + RENDERJS_MODULES]; + var module = __renderjsModules && __renderjsModules[moduleId]; + if (!module) { + return console.error(formatLog("renderjs", moduleId + " not found")); + } + return module; + } + function createRenderjsInstance(options) { + options = options.default || options; + options.render = () => { + }; + return createApp(options).mount(document.createElement("div")); + } class UniNode { constructor(id2, tag, parentNodeId, element) { this.isMounted = false; @@ -7809,6 +7860,7 @@ $2.parentNode.removeChild($2); this.isUnmounted = true; removeElement(this.id); + destroyRenderjs(this); } appendChild(node) { return this.$.appendChild(node); @@ -7822,7 +7874,7 @@ var propName = name.replace(ATTR_CHANGE_PREFIX, ""); var value = attrs2[propName]; var invoker = createWxsPropsInvoker(this, attrs2[name], value); - queuePostActionJob(() => invoker(value)); + queuePostActionJob(() => invoker(value), JOB_PRIORITY_WXS_PROPS); this.$wxsProps.set(name, invoker); delete attrs2[name]; delete attrs2[propName]; @@ -7838,10 +7890,10 @@ } addWxsEvent(name, wxsEvent, flag) { } - wxsPropsInvoke(name, value) { + wxsPropsInvoke(name, value, isNextTick = false) { var wxsPropsInvoker = this.$hasWxsProps && this.$wxsProps.get(ATTR_CHANGE_PREFIX + name); if (wxsPropsInvoker) { - return wxsPropsInvoker(value), true; + return queuePostActionJob(() => isNextTick ? nextTick(() => wxsPropsInvoker(value)) : wxsPropsInvoker(value), JOB_PRIORITY_WXS_PROPS), true; } } } @@ -7981,7 +8033,7 @@ } function createWxsEventInvoker(el, wxsEvent, flag) { var invoker = (evt) => { - invokeWxsEvent(wxsEvent, el, $nne(evt)[0]); + invokeWxsEvent(el, wxsEvent, $nne(evt)[0]); }; if (!flag) { return invoker; @@ -7989,14 +8041,14 @@ return withModifiers(invoker, resolveModifier(flag)); } var JSON_PROTOCOL_LEN = JSON_PROTOCOL.length; - function decodeAttr(value) { + function decodeAttr(el, value) { if (!isString(value)) { return value; } if (value.indexOf(JSON_PROTOCOL) === 0) { value = JSON.parse(value.substr(JSON_PROTOCOL_LEN)); } else if (value.indexOf(WXS_PROTOCOL) === 0) { - value = invokeWxs(value); + value = invokeWxs(el, value); } return value; } @@ -8030,7 +8082,7 @@ } super.init(nodeJson); watch(this.$props, () => { - queuePostActionJob(this._update); + queuePostActionJob(this._update, JOB_PRIORITY_UPDATE); }, { flush: "sync" }); @@ -8065,6 +8117,8 @@ patchVShow(this.$, value); } else if (name === ATTR_V_OWNER_ID) { this.$.__ownerId = value; + } else if (name === ATTR_V_RENDERJS) { + queuePostActionJob(() => initRenderjs(this, value), JOB_PRIORITY_RENDERJS); } else if (name === ATTR_INNER_HTML) { this.$.innerHTML = value; } else if (name === ATTR_TEXT_CONTENT) { @@ -8083,7 +8137,7 @@ } } setAttribute(name, value) { - value = decodeAttr(value); + value = decodeAttr(this.$, value); if (this.$propNames.indexOf(name) !== -1) { this.$props[name] = value; } else { @@ -16503,8 +16557,10 @@ } } else if (name === ATTR_V_OWNER_ID) { this.$.__ownerId = value; + } else if (name === ATTR_V_RENDERJS) { + queuePostActionJob(() => initRenderjs(this, value), JOB_PRIORITY_RENDERJS); } else if (name === ATTR_STYLE) { - var newStyle = decodeAttr(value); + var newStyle = decodeAttr(this.$ || $(this.pid).$, value); var oldStyle = this.$props.style; if (isPlainObject(newStyle) && isPlainObject(oldStyle)) { Object.keys(newStyle).forEach((n) => { @@ -16514,8 +16570,8 @@ this.$props.style = newStyle; } } else { - value = decodeAttr(value); - if (!this.wxsPropsInvoke(name, value)) { + value = decodeAttr(this.$ || $(this.pid).$, value); + if (!this.wxsPropsInvoke(name, value, true)) { this.$props[name] = value; } } @@ -16546,15 +16602,15 @@ return this._rebuild; } setText(text2) { - queuePostActionJob(this.getRebuildFn()); + queuePostActionJob(this.getRebuildFn(), JOB_PRIORITY_REBUILD); return super.setText(text2); } appendChild(node) { - queuePostActionJob(this.getRebuildFn()); + queuePostActionJob(this.getRebuildFn(), JOB_PRIORITY_REBUILD); return super.appendChild(node); } insertBefore(newChild, refChild) { - queuePostActionJob(this.getRebuildFn()); + queuePostActionJob(this.getRebuildFn(), JOB_PRIORITY_REBUILD); return super.insertBefore(newChild, refChild); } rebuild() { diff --git a/packages/uni-app-plus/src/view/framework/dom/components/UniComponent.ts b/packages/uni-app-plus/src/view/framework/dom/components/UniComponent.ts index f682bab4a89188f44af2dade407ef8f81ca6251c..d5de72fecc5512936fe4248ed54814a33b4ef171 100644 --- a/packages/uni-app-plus/src/view/framework/dom/components/UniComponent.ts +++ b/packages/uni-app-plus/src/view/framework/dom/components/UniComponent.ts @@ -11,6 +11,7 @@ import { import { ATTR_STYLE, ATTR_V_OWNER_ID, + ATTR_V_RENDERJS, ATTR_V_SHOW, formatLog, parseEventName, @@ -20,9 +21,14 @@ import { UniNode } from '../elements/UniNode' import { createInvoker, createWxsEventInvoker } from '../modules/events' import { createWrapper, UniCustomElement } from '.' import { $, removeElement } from '../page' -import { queuePostActionJob } from '../scheduler' +import { + JOB_PRIORITY_REBUILD, + JOB_PRIORITY_RENDERJS, + queuePostActionJob, +} from '../scheduler' import { decodeAttr } from '../utils' import { patchVShow, VShowElement } from '../directives/vShow' +import { initRenderjs } from '../renderjs' export class UniComponent extends UniNode { declare $: UniCustomElement @@ -106,8 +112,14 @@ export class UniComponent extends UniNode { } } else if (name === ATTR_V_OWNER_ID) { this.$.__ownerId = value as number + } else if (name === ATTR_V_RENDERJS) { + // 本轮渲染结束后初始化 + queuePostActionJob( + () => initRenderjs(this, value as Record), + JOB_PRIORITY_RENDERJS + ) } else if (name === ATTR_STYLE) { - const newStyle = decodeAttr(value) + const newStyle = decodeAttr(this.$ || $(this.pid).$, value) const oldStyle = this.$props.style if (isPlainObject(newStyle) && isPlainObject(oldStyle)) { Object.keys(newStyle).forEach((n) => { @@ -117,8 +129,8 @@ export class UniComponent extends UniNode { this.$props.style = newStyle } } else { - value = decodeAttr(value) - if (!this.wxsPropsInvoke(name, value)) { + value = decodeAttr(this.$ || $(this.pid).$, value) + if (!this.wxsPropsInvoke(name, value, true)) { this.$props[name] = value } } @@ -160,15 +172,15 @@ export class UniContainerComponent extends UniComponent { return this._rebuild } setText(text: string) { - queuePostActionJob(this.getRebuildFn()) + queuePostActionJob(this.getRebuildFn(), JOB_PRIORITY_REBUILD) return super.setText(text) } appendChild(node: Element) { - queuePostActionJob(this.getRebuildFn()) + queuePostActionJob(this.getRebuildFn(), JOB_PRIORITY_REBUILD) return super.appendChild(node) } insertBefore(newChild: Node, refChild: Node) { - queuePostActionJob(this.getRebuildFn()) + queuePostActionJob(this.getRebuildFn(), JOB_PRIORITY_REBUILD) return super.insertBefore(newChild, refChild) } rebuild() { diff --git a/packages/uni-app-plus/src/view/framework/dom/components/index.ts b/packages/uni-app-plus/src/view/framework/dom/components/index.ts index 92c47b95331133d340759e404a2076720c0ccfcf..5dc48bfb8e02c4fc71e9d43b08e25b326bacb95c 100644 --- a/packages/uni-app-plus/src/view/framework/dom/components/index.ts +++ b/packages/uni-app-plus/src/view/framework/dom/components/index.ts @@ -56,6 +56,8 @@ export interface UniCustomElement extends HTMLElement { __wxsRemoveClass: string[] __wxsClassChanged: boolean __wxsStyleChanged: boolean + // renderjs + __renderjsInstances?: Record } export const BuiltInComponents = { diff --git a/packages/uni-app-plus/src/view/framework/dom/elements/UniElement.ts b/packages/uni-app-plus/src/view/framework/dom/elements/UniElement.ts index f0c7234d1c7be70a9d209c8298920ca84e9bfb03..b58879ebf5ef20fe15df56256dbb1a872662b4d2 100644 --- a/packages/uni-app-plus/src/view/framework/dom/elements/UniElement.ts +++ b/packages/uni-app-plus/src/view/framework/dom/elements/UniElement.ts @@ -6,6 +6,7 @@ import { ATTR_TEXT_CONTENT, ATTR_V_SHOW, ATTR_V_OWNER_ID, + ATTR_V_RENDERJS, UniNodeJSON, } from '@dcloudio/uni-shared' import { reactive, watch } from 'vue' @@ -14,9 +15,14 @@ import { patchClass } from '../modules/class' import { patchStyle } from '../modules/style' import { patchEvent, patchWxsEvent } from '../modules/events' import { UniCustomElement } from '../components' -import { queuePostActionJob } from '../scheduler' +import { + JOB_PRIORITY_RENDERJS, + JOB_PRIORITY_UPDATE, + queuePostActionJob, +} from '../scheduler' import { decodeAttr } from '../utils' import { patchVShow, VShowElement } from '../directives/vShow' +import { initRenderjs } from '../renderjs' export class UniElement extends UniNode { declare $: UniCustomElement @@ -56,7 +62,7 @@ export class UniElement extends UniNode { watch( this.$props, () => { - queuePostActionJob(this._update!) + queuePostActionJob(this._update!, JOB_PRIORITY_UPDATE) }, { flush: 'sync' } ) @@ -93,6 +99,12 @@ export class UniElement extends UniNode { patchVShow(this.$ as VShowElement, value) } else if (name === ATTR_V_OWNER_ID) { this.$.__ownerId = value as number + } else if (name === ATTR_V_RENDERJS) { + // 本轮渲染结束后初始化 + queuePostActionJob( + () => initRenderjs(this, value as Record), + JOB_PRIORITY_RENDERJS + ) } else if (name === ATTR_INNER_HTML) { this.$.innerHTML = value as string } else if (name === ATTR_TEXT_CONTENT) { @@ -116,7 +128,7 @@ export class UniElement extends UniNode { } } setAttribute(name: string, value: unknown) { - value = decodeAttr(value) + value = decodeAttr(this.$, value) if (this.$propNames.indexOf(name) !== -1) { ;(this.$props as any)[name] = value } else { diff --git a/packages/uni-app-plus/src/view/framework/dom/elements/UniNode.ts b/packages/uni-app-plus/src/view/framework/dom/elements/UniNode.ts index 24c9cbe4f95f32fd21fb203b7f6a9f36e21832ba..775db79bffcd69e9bbbafc4543892807bec7b3b0 100644 --- a/packages/uni-app-plus/src/view/framework/dom/elements/UniNode.ts +++ b/packages/uni-app-plus/src/view/framework/dom/elements/UniNode.ts @@ -2,8 +2,10 @@ import { hasOwn } from '@vue/shared' import { ATTR_CHANGE_PREFIX, UniNodeJSON } from '@dcloudio/uni-shared' import { $, removeElement } from '../page' -import { queuePostActionJob } from '../scheduler' +import { JOB_PRIORITY_WXS_PROPS, queuePostActionJob } from '../scheduler' import { createWxsPropsInvoker, WxsPropsInvoker } from '../wxs' +import { destroyRenderjs } from '../renderjs' +import { nextTick } from 'vue' export class UniNode { id: number @@ -51,6 +53,7 @@ export class UniNode { $.parentNode!.removeChild($) this.isUnmounted = true removeElement(this.id) + destroyRenderjs(this) } appendChild(node: Node) { return this.$.appendChild(node) @@ -65,7 +68,7 @@ export class UniNode { const value = attrs[propName] const invoker = createWxsPropsInvoker(this, attrs[name], value) // 队列后再执行 - queuePostActionJob(() => invoker(value)) + queuePostActionJob(() => invoker(value), JOB_PRIORITY_WXS_PROPS) this.$wxsProps.set(name, invoker) delete attrs[name] delete attrs[propName] @@ -80,11 +83,22 @@ export class UniNode { }) } addWxsEvent(name: string, wxsEvent: string, flag: number) {} - wxsPropsInvoke(name: string, value: unknown) { + wxsPropsInvoke(name: string, value: unknown, isNextTick = false) { const wxsPropsInvoker = this.$hasWxsProps && this.$wxsProps.get(ATTR_CHANGE_PREFIX + name) if (wxsPropsInvoker) { - return wxsPropsInvoker(value), true + return ( + // 等待其他属性先更新,因为开发者可能在invoker中获取当前节点的最新属性信息 + // vue组件中的change:props需要nextTick后执行,普通element,队列后执行 + queuePostActionJob( + () => + isNextTick + ? nextTick(() => wxsPropsInvoker(value)) + : wxsPropsInvoker(value), + JOB_PRIORITY_WXS_PROPS + ), + true + ) } } } diff --git a/packages/uni-app-plus/src/view/framework/dom/modules/events.ts b/packages/uni-app-plus/src/view/framework/dom/modules/events.ts index 0c73beee8a5282df64d722642d38aabf436def83..5b21a947660d3f8407b4dc59053c5de951d462a7 100644 --- a/packages/uni-app-plus/src/view/framework/dom/modules/events.ts +++ b/packages/uni-app-plus/src/view/framework/dom/modules/events.ts @@ -114,8 +114,8 @@ export function createWxsEventInvoker( ) { const invoker = (evt: Event) => { invokeWxsEvent( - wxsEvent, el, + wxsEvent, normalizeNativeEvent(evt)[0] as Record ) } diff --git a/packages/uni-app-plus/src/view/framework/dom/renderjs.ts b/packages/uni-app-plus/src/view/framework/dom/renderjs.ts new file mode 100644 index 0000000000000000000000000000000000000000..e29af65dbc640ad930aa7a12947b328bebe13768 --- /dev/null +++ b/packages/uni-app-plus/src/view/framework/dom/renderjs.ts @@ -0,0 +1,49 @@ +import { createApp, ComponentOptions, ComponentPublicInstance } from 'vue' +import { formatLog, RENDERJS_MODULES } from '@dcloudio/uni-shared' + +import { UniNode } from './elements/UniNode' +import { UniCustomElement } from './components' + +export function initRenderjs(node: UniNode, moduleIds: Record) { + Object.keys(moduleIds).forEach((name) => { + initRenderjsModule(node, moduleIds[name]) + }) +} + +export function destroyRenderjs(node: UniNode) { + const { __renderjsInstances } = node.$ as UniCustomElement + if (!__renderjsInstances) { + return + } + Object.keys(__renderjsInstances).forEach((id) => { + __renderjsInstances[id].$.appContext.app.unmount() + }) +} + +function initRenderjsModule(node: UniNode, moduleId: string) { + const options = getRenderjsModule(moduleId) + if (!options) { + return + } + const el = node.$ as UniCustomElement + ;(el.__renderjsInstances || (el.__renderjsInstances = {}))[moduleId] = + createRenderjsInstance(options) +} + +function getRenderjsModule(moduleId: string) { + const __renderjsModules = + window[('__' + RENDERJS_MODULES) as '__renderjsModules'] + const module = __renderjsModules && __renderjsModules[moduleId] + if (!module) { + return console.error(formatLog('renderjs', moduleId + ' not found')) + } + return module as ComponentOptions | { default: ComponentOptions } +} + +function createRenderjsInstance( + options: ComponentOptions +): ComponentPublicInstance { + options = options.default || options + options.render = () => {} + return createApp(options).mount(document.createElement('div')) +} diff --git a/packages/uni-app-plus/src/view/framework/dom/scheduler.ts b/packages/uni-app-plus/src/view/framework/dom/scheduler.ts index a845aeaeb0fc302e817e647d4915c409c26e84fd..8202c4bd1f54316e8e5d5cf56639f5446fb5173c 100644 --- a/packages/uni-app-plus/src/view/framework/dom/scheduler.ts +++ b/packages/uni-app-plus/src/view/framework/dom/scheduler.ts @@ -1,15 +1,38 @@ import { formatLog } from '@dcloudio/uni-shared' -const postActionJobs = new Set() -export function queuePostActionJob(job: Function) { - postActionJobs.add(job) +interface ActionJob { + (): void + priority: number } + +function createActionJob(fn: Function, priority: number) { + return ((fn as ActionJob).priority = priority), fn as ActionJob +} + +const postActionJobs = new Set() +// 升序排列 +export const JOB_PRIORITY_DEFAULT = 0 +// 组件自身 update,比如 hover 类组件需要初始化事件 +export const JOB_PRIORITY_UPDATE = 1 +// 容器组件重建 +export const JOB_PRIORITY_REBUILD = 2 +// 初始化 renderjs 实例 +export const JOB_PRIORITY_RENDERJS = 3 +// 初始化触发 wxs 的 change:prop,前置条件 renderjs 实例被初始化 +export const JOB_PRIORITY_WXS_PROPS = 4 + +export function queuePostActionJob(job: Function, priority: number) { + postActionJobs.add(createActionJob(job, priority)) +} + export function flushPostActionJobs() { if (__DEV__) { console.log(formatLog(`flushPostActionJobs`, postActionJobs.size)) } try { - postActionJobs.forEach((fn) => fn()) + ;[...postActionJobs] + .sort((a, b) => a.priority - b.priority) + .forEach((fn) => fn()) } finally { postActionJobs.clear() } diff --git a/packages/uni-app-plus/src/view/framework/dom/utils.ts b/packages/uni-app-plus/src/view/framework/dom/utils.ts index d4cab6b6b36f33feafd77b1e5e3286aef30b6872..036ecc4c3d761eab1c50454b0089df4db8c5c2de 100644 --- a/packages/uni-app-plus/src/view/framework/dom/utils.ts +++ b/packages/uni-app-plus/src/view/framework/dom/utils.ts @@ -1,17 +1,18 @@ import { JSON_PROTOCOL, WXS_PROTOCOL } from '@dcloudio/uni-shared' import { isString } from '@vue/shared' +import { UniCustomElement } from './components' import { invokeWxs } from './wxs' const JSON_PROTOCOL_LEN = JSON_PROTOCOL.length -export function decodeAttr(value: unknown) { +export function decodeAttr(el: UniCustomElement, value: unknown) { if (!isString(value)) { return value } if (value.indexOf(JSON_PROTOCOL) === 0) { value = JSON.parse(value.substr(JSON_PROTOCOL_LEN)) } else if (value.indexOf(WXS_PROTOCOL) === 0) { - value = invokeWxs(value) + value = invokeWxs(el, value) } return value } diff --git a/packages/uni-app-plus/src/view/framework/dom/wxs.ts b/packages/uni-app-plus/src/view/framework/dom/wxs.ts index 1ecc993dcbd9f6cf300ac45b3255c8020836114f..939e8b47cff2f82e114028d4269b0ad83495e5a6 100644 --- a/packages/uni-app-plus/src/view/framework/dom/wxs.ts +++ b/packages/uni-app-plus/src/view/framework/dom/wxs.ts @@ -4,7 +4,6 @@ import { getValueByDataPath, WXS_PROTOCOL, WXS_MODULES, - RENDERJS_MODULES, } from '@dcloudio/uni-shared' import { ComponentDescriptorVm, @@ -24,54 +23,51 @@ declare global { } } -function getWxsModule(moduleId: string) { +function getViewModule(moduleId: string, ownerEl: UniCustomElement) { const __wxsModules = window[('__' + WXS_MODULES) as '__wxsModules'] - const __renderjsModules = - window[('__' + RENDERJS_MODULES) as '__renderjsModules'] - let module = __wxsModules && __wxsModules[moduleId] - if (!module) { - module = __renderjsModules && __renderjsModules[moduleId] + const module = __wxsModules && __wxsModules[moduleId] + if (module) { + return module } - if (!module) { - return console.error(formatLog('wxs or renderjs', moduleId + ' not found')) + if (ownerEl && ownerEl.__renderjsInstances) { + return ownerEl.__renderjsInstances[moduleId] } - return module } const WXS_PROTOCOL_LEN = WXS_PROTOCOL.length -export function invokeWxs(wxsStr: string, invokerArgs?: unknown[]) { - const [, moduleId, invoker, args] = JSON.parse( - wxsStr.substr(WXS_PROTOCOL_LEN) - ) +export function invokeWxs( + el: UniCustomElement | undefined, + wxsStr: string, + invokerArgs?: unknown[] +) { + const [ownerId, moduleId, invoker, args] = parseWxs(wxsStr) + const ownerEl = resolveOwnerEl(el!, ownerId) if (isArray(invokerArgs) || isArray(args)) { // methods const [moduleName, mehtodName] = invoker.split('.') return invokeWxsMethod( + ownerEl, moduleId, moduleName, mehtodName, invokerArgs || args ) } - return getWxsProp(moduleId, invoker) + return getWxsProp(ownerEl, moduleId, invoker) } export function invokeWxsEvent( - wxsStr: string, el: UniCustomElement, + wxsStr: string, event: Record ) { - const [ownerId, moduleId, invoker] = JSON.parse( - wxsStr.substr(WXS_PROTOCOL_LEN) - ) + const [ownerId, moduleId, invoker] = parseWxs(wxsStr) const [moduleName, mehtodName] = invoker.split('.') - return invokeWxsMethod(moduleId, moduleName, mehtodName, [ + const ownerEl = resolveOwnerEl(el, ownerId) + return invokeWxsMethod(ownerEl, moduleId, moduleName, mehtodName, [ wrapperWxsEvent(event, el), - getComponentDescriptor( - createComponentDescriptorVm(resolveOwnerEl(el, ownerId)), - false - ), + getComponentDescriptor(createComponentDescriptorVm(ownerEl), false), ]) } @@ -89,34 +85,40 @@ function resolveOwnerEl(el: UniCustomElement, ownerId: number) { return el } +function parseWxs(wxsStr: string) { + return JSON.parse(wxsStr.substr(WXS_PROTOCOL_LEN)) as [ + number, + string, + string, + any + ] +} + export function invokeWxsProps( wxsStr: string, el: UniCustomElement, newValue: unknown, oldValue: unknown ) { - const [ownerId, moduleId, invoker] = JSON.parse( - wxsStr.substr(WXS_PROTOCOL_LEN) - ) + const [ownerId, moduleId, invoker] = parseWxs(wxsStr) + const ownerEl = resolveOwnerEl(el, ownerId) const [moduleName, mehtodName] = invoker.split('.') - return invokeWxsMethod(moduleId, moduleName, mehtodName, [ + return invokeWxsMethod(ownerEl, moduleId, moduleName, mehtodName, [ newValue, oldValue, - getComponentDescriptor( - createComponentDescriptorVm(resolveOwnerEl(el, ownerId)), - false - ), + getComponentDescriptor(createComponentDescriptorVm(ownerEl), false), getComponentDescriptor(createComponentDescriptorVm(el), false), ]) } function invokeWxsMethod( + ownerEl: UniCustomElement, moduleId: string, moduleName: string, methodName: string, args: unknown[] ) { - const module = getWxsModule(moduleId) + const module = getViewModule(moduleId, ownerEl) if (!module) { return console.error( formatLog('wxs', 'module ' + moduleName + ' not found') @@ -129,8 +131,12 @@ function invokeWxsMethod( return method.apply(module, args) } -function getWxsProp(moduleId: string, dataPath: string) { - const module = getWxsModule(moduleId) +function getWxsProp( + ownerEl: UniCustomElement, + moduleId: string, + dataPath: string +) { + const module = getViewModule(moduleId, ownerEl) if (!module) { return console.error(formatLog('wxs', 'module ' + dataPath + ' not found')) } diff --git a/packages/uni-app-vue/dist/service.runtime.esm.js b/packages/uni-app-vue/dist/service.runtime.esm.js index 1fc96e5cd3d7552c12d3533d702ab5940b0e31b9..32df3f25c3053eabade9ca307534e03642b3cd35 100644 --- a/packages/uni-app-vue/dist/service.runtime.esm.js +++ b/packages/uni-app-vue/dist/service.runtime.esm.js @@ -37,6 +37,36 @@ export default function vueFactory(exports) { */ var capitalize$1 = cacheStringFunction$1(str => str.charAt(0).toUpperCase() + str.slice(1)); + + function isElement(el) { + // Element + return el.nodeType === 1; + } + + function resolveOwnerEl(instance) { + var { + vnode + } = instance; + + if (isElement(vnode.el)) { + return vnode.el; + } + + var { + subTree + } = instance; // ShapeFlags.ARRAY_CHILDREN = 1<<4 + + if (subTree.shapeFlag & 16) { + var elemVNode = subTree.children.find(vnode => isElement(vnode.el)); + + if (elemVNode) { + return elemVNode.el; + } + } + + return vnode.el; + } + var lastLogTime = 0; function formatLog(module, ...args) { @@ -380,6 +410,8 @@ export default function vueFactory(exports) { var ATTR_CLASS = 'class'; var ATTR_STYLE = 'style'; + var ATTR_V_OWNER_ID = '.vOwnerId'; + var ATTR_V_RENDERJS = '.vRenderjs'; class UniBaseNode extends UniNode { constructor(nodeType, nodeName, container) { @@ -7851,15 +7883,14 @@ export default function vueFactory(exports) { setupRenderEffect(instance, initialVNode, container, anchor, parentSuspense, isSVG, optimized); // fixed by xxxxxx 对根节点设置ownerid if (instance.$wxsModules) { - var vnode = instance.subTree; + var el = resolveOwnerEl(instance); - if (vnode.shapeFlag & 16 - /* ARRAY_CHILDREN */ - ) { - var elemVNode = vnode.children.find(vnode => vnode.shapeFlag & 1 - /* ELEMENT */ - ); - elemVNode && elemVNode.el.setAttribute('.vOwnerId', instance.uid); + if (el) { + el.setAttribute(ATTR_V_OWNER_ID, instance.uid); + var { + $renderjsModules + } = instance.type; + $renderjsModules && el.setAttribute(ATTR_V_RENDERJS, $renderjsModules); } } diff --git a/packages/uni-app-vue/lib/service.runtime.esm.js b/packages/uni-app-vue/lib/service.runtime.esm.js index 409690ece5b7167636dd321fe5f388ee67d724ec..85df5efc1c605c6255a667af95789a19c0d83994 100644 --- a/packages/uni-app-vue/lib/service.runtime.esm.js +++ b/packages/uni-app-vue/lib/service.runtime.esm.js @@ -1,4 +1,4 @@ -import { isRootHook, UniInputElement, UniTextAreaElement, UniElement, UniTextNode, UniCommentNode, JSON_PROTOCOL } from '@dcloudio/uni-shared'; +import { isRootHook, resolveOwnerEl, ATTR_V_OWNER_ID, ATTR_V_RENDERJS, UniInputElement, UniTextAreaElement, UniElement, UniTextNode, UniCommentNode, JSON_PROTOCOL } from '@dcloudio/uni-shared'; /** * Make a map and return a function for checking if a key @@ -6301,10 +6301,11 @@ function baseCreateRenderer(options, createHydrationFns) { setupRenderEffect(instance, initialVNode, container, anchor, parentSuspense, isSVG, optimized); // fixed by xxxxxx 对根节点设置ownerid if (instance.$wxsModules) { - const vnode = instance.subTree; - if (vnode.shapeFlag & 16 /* ARRAY_CHILDREN */) { - const elemVNode = vnode.children.find(vnode => vnode.shapeFlag & 1 /* ELEMENT */); - elemVNode && elemVNode.el.setAttribute('.vOwnerId', instance.uid); + const el = resolveOwnerEl(instance); + if (el) { + el.setAttribute(ATTR_V_OWNER_ID, instance.uid); + const { $renderjsModules } = instance.type; + $renderjsModules && el.setAttribute(ATTR_V_RENDERJS, $renderjsModules); } } if ((process.env.NODE_ENV !== 'production')) { diff --git a/packages/uni-core/src/view/plugin/componentWxs.ts b/packages/uni-core/src/view/plugin/componentWxs.ts index 0a39270addc763444f858907a4eee4e059a9738c..d04bedbf97d4fd2207a9eee0158494c849f902af 100644 --- a/packages/uni-core/src/view/plugin/componentWxs.ts +++ b/packages/uni-core/src/view/plugin/componentWxs.ts @@ -1,11 +1,15 @@ -import { ComponentInternalInstance, ComponentPublicInstance, VNode } from 'vue' +import { ComponentInternalInstance, ComponentPublicInstance } from 'vue' import { isFunction, isPlainObject, parseStringStyle, stringifyStyle, } from '@vue/shared' -import { ON_WXS_INVOKE_CALL_METHOD, resolveOwnerVm } from '@dcloudio/uni-shared' +import { + ON_WXS_INVOKE_CALL_METHOD, + resolveOwnerEl, + resolveOwnerVm, +} from '@dcloudio/uni-shared' export interface WxsElement extends HTMLElement { __id?: number @@ -26,24 +30,6 @@ export interface ComponentDescriptorVm { $forceUpdate: any } -function ensureEl(vm: ComponentPublicInstance) { - // 确保el是有效节点(不然的话,可能是text或comment) - const vnode = vm.$.subTree - // ShapeFlags.ARRAY_CHILDREN = 1 << 4 - // ShapeFlags.ELEMENT = 1 - - if (vnode.shapeFlag & (1 << 4)) { - const elemVNode = (vnode.children as VNode[]).find( - // element || component - (vnode) => vnode.shapeFlag & 1 || vnode.shapeFlag & 6 - ) - if (elemVNode) { - return elemVNode.el - } - } - return vm.$el -} - export class ComponentDescriptor { private $vm: ComponentDescriptorVm private $el: WxsElement @@ -52,7 +38,7 @@ export class ComponentDescriptor { constructor(vm: ComponentDescriptorVm) { this.$vm = vm if (__PLATFORM__ === 'h5') { - this.$el = ensureEl(vm as ComponentPublicInstance) + this.$el = resolveOwnerEl((vm as ComponentPublicInstance).$) as WxsElement } else { this.$el = vm.$el } diff --git a/packages/uni-h5/dist/uni-h5.es.js b/packages/uni-h5/dist/uni-h5.es.js index 08dd6b663fa44c8e2402bee5bc3d88cb11c7990a..54579e782f7aca7fef8408b84c60e164bd737995 100644 --- a/packages/uni-h5/dist/uni-h5.es.js +++ b/packages/uni-h5/dist/uni-h5.es.js @@ -1,5 +1,5 @@ import { withModifiers, createVNode, getCurrentInstance, defineComponent, ref, provide, computed, watch, onUnmounted, inject, onBeforeUnmount, mergeProps, reactive, onActivated, onMounted, nextTick, onBeforeMount, withDirectives, vShow, shallowRef, watchEffect, isVNode, Fragment, markRaw, createTextVNode, injectHook, onBeforeActivate, onBeforeDeactivate, openBlock, createBlock, renderList, onDeactivated, createApp, Transition, withCtx, KeepAlive, resolveDynamicComponent, renderSlot } from "vue"; -import { once, passive, initCustomDataset, invokeArrayFns, resolveOwnerVm, ON_WXS_INVOKE_CALL_METHOD, normalizeTarget, ON_RESIZE, ON_APP_ENTER_FOREGROUND, ON_APP_ENTER_BACKGROUND, ON_SHOW, ON_HIDE, ON_PAGE_SCROLL, ON_REACH_BOTTOM, EventChannel, SCHEME_RE, DATA_RE, getCustomDataset, ON_ERROR, callOptions, PRIMARY_COLOR, removeLeadingSlash, getLen, debounce, NAVBAR_HEIGHT, parseQuery, ON_UNLOAD, ON_REACH_BOTTOM_DISTANCE, decodedQuery, WEB_INVOKE_APPSERVICE, ON_WEB_INVOKE_APP_SERVICE, updateElementStyle, ON_BACK_PRESS, parseUrl, addFont, scrollTo, RESPONSIVE_MIN_WIDTH, formatDateTime, ON_PULL_DOWN_REFRESH } from "@dcloudio/uni-shared"; +import { once, passive, initCustomDataset, invokeArrayFns, resolveOwnerVm, resolveOwnerEl, ON_WXS_INVOKE_CALL_METHOD, normalizeTarget, ON_RESIZE, ON_APP_ENTER_FOREGROUND, ON_APP_ENTER_BACKGROUND, ON_SHOW, ON_HIDE, ON_PAGE_SCROLL, ON_REACH_BOTTOM, EventChannel, SCHEME_RE, DATA_RE, getCustomDataset, ON_ERROR, callOptions, PRIMARY_COLOR, removeLeadingSlash, getLen, debounce, NAVBAR_HEIGHT, parseQuery, ON_UNLOAD, ON_REACH_BOTTOM_DISTANCE, decodedQuery, WEB_INVOKE_APPSERVICE, ON_WEB_INVOKE_APP_SERVICE, updateElementStyle, ON_BACK_PRESS, parseUrl, addFont, scrollTo, RESPONSIVE_MIN_WIDTH, formatDateTime, ON_PULL_DOWN_REFRESH } from "@dcloudio/uni-shared"; import { initVueI18n, LOCALE_EN, LOCALE_ES, LOCALE_FR, LOCALE_ZH_HANS, LOCALE_ZH_HANT } from "@dcloudio/uni-i18n"; import { extend, isString, stringifyStyle, parseStringStyle, isPlainObject, isFunction, isArray, hasOwn, isObject, capitalize, toRawType, makeMap as makeMap$1, isPromise, hyphenate, invokeArrayFns as invokeArrayFns$1 } from "@vue/shared"; import { useRoute, createRouter, createWebHistory, createWebHashHistory, useRouter, isNavigationFailure, RouterView } from "vue-router"; @@ -867,23 +867,13 @@ function getRouteOptions(path, alias = false) { } return __uniRoutes.find((route) => route.path === path); } -function ensureEl(vm) { - const vnode = vm.$.subTree; - if (vnode.shapeFlag & 1 << 4) { - const elemVNode = vnode.children.find((vnode2) => vnode2.shapeFlag & 1); - if (elemVNode) { - return elemVNode.el; - } - } - return vm.$el; -} class ComponentDescriptor { constructor(vm) { this.$bindClass = false; this.$bindStyle = false; this.$vm = vm; { - this.$el = ensureEl(vm); + this.$el = resolveOwnerEl(vm.$); } if (this.$el.getAttribute) { this.$bindClass = !!this.$el.getAttribute("class"); diff --git a/packages/uni-shared/dist/uni-shared.cjs.js b/packages/uni-shared/dist/uni-shared.cjs.js index 46e3a20297d804ac7d68e05efa61f9b11a136496..ac178bb7dcb12aa32d780bfb1064110c7003e5c0 100644 --- a/packages/uni-shared/dist/uni-shared.cjs.js +++ b/packages/uni-shared/dist/uni-shared.cjs.js @@ -96,6 +96,25 @@ function resolveOwnerVm(vm) { componentName = vm.type.name; } return vm.proxy; +} +function isElement(el) { + // Element + return el.nodeType === 1; +} +function resolveOwnerEl(instance) { + const { vnode } = instance; + if (isElement(vnode.el)) { + return vnode.el; + } + const { subTree } = instance; + // ShapeFlags.ARRAY_CHILDREN = 1<<4 + if (subTree.shapeFlag & 16) { + const elemVNode = subTree.children.find((vnode) => isElement(vnode.el)); + if (elemVNode) { + return elemVNode.el; + } + } + return vnode.el; } let lastLogTime = 0; @@ -589,6 +608,7 @@ const ATTR_INNER_HTML = 'innerHTML'; const ATTR_TEXT_CONTENT = 'textContent'; const ATTR_V_SHOW = '.vShow'; const ATTR_V_OWNER_ID = '.vOwnerId'; +const ATTR_V_RENDERJS = '.vRenderjs'; const ATTR_CHANGE_PREFIX = 'change:'; class UniBaseNode extends UniNode { constructor(nodeType, nodeName, container) { @@ -1022,6 +1042,7 @@ exports.ATTR_INNER_HTML = ATTR_INNER_HTML; exports.ATTR_STYLE = ATTR_STYLE; exports.ATTR_TEXT_CONTENT = ATTR_TEXT_CONTENT; exports.ATTR_V_OWNER_ID = ATTR_V_OWNER_ID; +exports.ATTR_V_RENDERJS = ATTR_V_RENDERJS; exports.ATTR_V_SHOW = ATTR_V_SHOW; exports.BACKGROUND_COLOR = BACKGROUND_COLOR; exports.BUILT_IN_TAGS = BUILT_IN_TAGS; @@ -1125,6 +1146,7 @@ exports.parseUrl = parseUrl; exports.passive = passive; exports.plusReady = plusReady; exports.removeLeadingSlash = removeLeadingSlash; +exports.resolveOwnerEl = resolveOwnerEl; exports.resolveOwnerVm = resolveOwnerVm; exports.sanitise = sanitise; exports.scrollTo = scrollTo; diff --git a/packages/uni-shared/dist/uni-shared.d.ts b/packages/uni-shared/dist/uni-shared.d.ts index 944392626b58d79087d271817f0afc9bc96e5705..86bda04e8505c9ae617010e229a6add985eb3c31 100644 --- a/packages/uni-shared/dist/uni-shared.d.ts +++ b/packages/uni-shared/dist/uni-shared.d.ts @@ -2,6 +2,7 @@ import { ComponentInternalInstance } from 'vue'; import { ComponentOptionsBase } from 'vue'; import { ComponentPublicInstance } from 'vue'; import { FontFaceDescriptors } from 'css-font-loading-module'; +import { RendererNode } from 'vue'; export declare const ACTION_TYPE_ADD_EVENT = 8; @@ -69,6 +70,8 @@ export declare const ATTR_TEXT_CONTENT = "textContent"; export declare const ATTR_V_OWNER_ID = ".vOwnerId"; +export declare const ATTR_V_RENDERJS = ".vRenderjs"; + export declare const ATTR_V_SHOW = ".vShow"; export declare const BACKGROUND_COLOR = "#f7f7f7"; @@ -403,6 +406,8 @@ export declare function removeLeadingSlash(str: string): string; export declare const RENDERJS_MODULES = "renderjsModules"; +export declare function resolveOwnerEl(instance: ComponentInternalInstance): RendererNode | null; + export declare function resolveOwnerVm(vm: ComponentInternalInstance): ComponentPublicInstance< {}, {}, {}, {}, {}, {}, {}, {}, false, ComponentOptionsBase> | undefined; export declare const RESPONSIVE_MIN_WIDTH = 768; diff --git a/packages/uni-shared/dist/uni-shared.es.js b/packages/uni-shared/dist/uni-shared.es.js index 6fd74fb70f8e3eb2de12427bb556e8877ce18e97..dd2bebcf26279e60a9f460f8eb050c15b2c00e14 100644 --- a/packages/uni-shared/dist/uni-shared.es.js +++ b/packages/uni-shared/dist/uni-shared.es.js @@ -92,6 +92,25 @@ function resolveOwnerVm(vm) { componentName = vm.type.name; } return vm.proxy; +} +function isElement(el) { + // Element + return el.nodeType === 1; +} +function resolveOwnerEl(instance) { + const { vnode } = instance; + if (isElement(vnode.el)) { + return vnode.el; + } + const { subTree } = instance; + // ShapeFlags.ARRAY_CHILDREN = 1<<4 + if (subTree.shapeFlag & 16) { + const elemVNode = subTree.children.find((vnode) => isElement(vnode.el)); + if (elemVNode) { + return elemVNode.el; + } + } + return vnode.el; } let lastLogTime = 0; @@ -585,6 +604,7 @@ const ATTR_INNER_HTML = 'innerHTML'; const ATTR_TEXT_CONTENT = 'textContent'; const ATTR_V_SHOW = '.vShow'; const ATTR_V_OWNER_ID = '.vOwnerId'; +const ATTR_V_RENDERJS = '.vRenderjs'; const ATTR_CHANGE_PREFIX = 'change:'; class UniBaseNode extends UniNode { constructor(nodeType, nodeName, container) { @@ -999,4 +1019,4 @@ function getEnvLocale() { return (lang && lang.replace(/[.:].*/, '')) || 'en'; } -export { ACTION_TYPE_ADD_EVENT, ACTION_TYPE_ADD_WXS_EVENT, ACTION_TYPE_CREATE, ACTION_TYPE_EVENT, ACTION_TYPE_INSERT, ACTION_TYPE_PAGE_CREATE, ACTION_TYPE_PAGE_CREATED, ACTION_TYPE_PAGE_SCROLL, ACTION_TYPE_REMOVE, ACTION_TYPE_REMOVE_ATTRIBUTE, ACTION_TYPE_REMOVE_EVENT, ACTION_TYPE_SET_ATTRIBUTE, ACTION_TYPE_SET_TEXT, ATTR_CHANGE_PREFIX, ATTR_CLASS, ATTR_INNER_HTML, ATTR_STYLE, ATTR_TEXT_CONTENT, ATTR_V_OWNER_ID, ATTR_V_SHOW, BACKGROUND_COLOR, BUILT_IN_TAGS, COMPONENT_NAME_PREFIX, COMPONENT_PREFIX, COMPONENT_SELECTOR_PREFIX, DATA_RE, EventChannel, EventModifierFlags, JSON_PROTOCOL, NAVBAR_HEIGHT, NODE_TYPE_COMMENT, NODE_TYPE_ELEMENT, NODE_TYPE_PAGE, NODE_TYPE_TEXT, ON_ADD_TO_FAVORITES, ON_APP_ENTER_BACKGROUND, ON_APP_ENTER_FOREGROUND, ON_BACK_PRESS, ON_ERROR, ON_HIDE, ON_KEYBOARD_HEIGHT_CHANGE, ON_LAUNCH, ON_LOAD, ON_NAVIGATION_BAR_BUTTON_TAP, ON_NAVIGATION_BAR_SEARCH_INPUT_CHANGED, ON_NAVIGATION_BAR_SEARCH_INPUT_CLICKED, ON_NAVIGATION_BAR_SEARCH_INPUT_CONFIRMED, ON_NAVIGATION_BAR_SEARCH_INPUT_FOCUS_CHANGED, ON_PAGE_NOT_FOUND, ON_PAGE_SCROLL, ON_PULL_DOWN_REFRESH, ON_REACH_BOTTOM, ON_REACH_BOTTOM_DISTANCE, ON_READY, ON_RESIZE, ON_SHARE_APP_MESSAGE, ON_SHARE_TIMELINE, ON_SHOW, ON_TAB_ITEM_TAP, ON_THEME_CHANGE, ON_UNHANDLE_REJECTION, ON_UNLOAD, ON_WEB_INVOKE_APP_SERVICE, ON_WXS_INVOKE_CALL_METHOD, PLUS_RE, PRIMARY_COLOR, RENDERJS_MODULES, RESPONSIVE_MIN_WIDTH, SCHEME_RE, SELECTED_COLOR, TABBAR_HEIGHT, TAGS, UNI_SSR, UNI_SSR_DATA, UNI_SSR_GLOBAL_DATA, UNI_SSR_STORE, UNI_SSR_TITLE, UniBaseNode, UniCommentNode, UniElement, UniEvent, UniInputElement, UniNode, UniTextAreaElement, UniTextNode, WEB_INVOKE_APPSERVICE, WXS_MODULES, WXS_PROTOCOL, addFont, cache, cacheStringFunction, callOptions, createRpx2Unit, createUniEvent, debounce, decode, decodedQuery, defaultRpx2Unit, formatDateTime, formatLog, getCustomDataset, getEnvLocale, getLen, getValueByDataPath, initCustomDataset, invokeArrayFns, isBuiltInComponent, isCustomElement, isNativeTag, isRootHook, isServiceCustomElement, isServiceNativeTag, normalizeDataset, normalizeEventType, normalizeTarget, once, parseEventName, parseQuery, parseUrl, passive, plusReady, removeLeadingSlash, resolveOwnerVm, sanitise, scrollTo, stringifyQuery, updateElementStyle }; +export { ACTION_TYPE_ADD_EVENT, ACTION_TYPE_ADD_WXS_EVENT, ACTION_TYPE_CREATE, ACTION_TYPE_EVENT, ACTION_TYPE_INSERT, ACTION_TYPE_PAGE_CREATE, ACTION_TYPE_PAGE_CREATED, ACTION_TYPE_PAGE_SCROLL, ACTION_TYPE_REMOVE, ACTION_TYPE_REMOVE_ATTRIBUTE, ACTION_TYPE_REMOVE_EVENT, ACTION_TYPE_SET_ATTRIBUTE, ACTION_TYPE_SET_TEXT, ATTR_CHANGE_PREFIX, ATTR_CLASS, ATTR_INNER_HTML, ATTR_STYLE, ATTR_TEXT_CONTENT, ATTR_V_OWNER_ID, ATTR_V_RENDERJS, ATTR_V_SHOW, BACKGROUND_COLOR, BUILT_IN_TAGS, COMPONENT_NAME_PREFIX, COMPONENT_PREFIX, COMPONENT_SELECTOR_PREFIX, DATA_RE, EventChannel, EventModifierFlags, JSON_PROTOCOL, NAVBAR_HEIGHT, NODE_TYPE_COMMENT, NODE_TYPE_ELEMENT, NODE_TYPE_PAGE, NODE_TYPE_TEXT, ON_ADD_TO_FAVORITES, ON_APP_ENTER_BACKGROUND, ON_APP_ENTER_FOREGROUND, ON_BACK_PRESS, ON_ERROR, ON_HIDE, ON_KEYBOARD_HEIGHT_CHANGE, ON_LAUNCH, ON_LOAD, ON_NAVIGATION_BAR_BUTTON_TAP, ON_NAVIGATION_BAR_SEARCH_INPUT_CHANGED, ON_NAVIGATION_BAR_SEARCH_INPUT_CLICKED, ON_NAVIGATION_BAR_SEARCH_INPUT_CONFIRMED, ON_NAVIGATION_BAR_SEARCH_INPUT_FOCUS_CHANGED, ON_PAGE_NOT_FOUND, ON_PAGE_SCROLL, ON_PULL_DOWN_REFRESH, ON_REACH_BOTTOM, ON_REACH_BOTTOM_DISTANCE, ON_READY, ON_RESIZE, ON_SHARE_APP_MESSAGE, ON_SHARE_TIMELINE, ON_SHOW, ON_TAB_ITEM_TAP, ON_THEME_CHANGE, ON_UNHANDLE_REJECTION, ON_UNLOAD, ON_WEB_INVOKE_APP_SERVICE, ON_WXS_INVOKE_CALL_METHOD, PLUS_RE, PRIMARY_COLOR, RENDERJS_MODULES, RESPONSIVE_MIN_WIDTH, SCHEME_RE, SELECTED_COLOR, TABBAR_HEIGHT, TAGS, UNI_SSR, UNI_SSR_DATA, UNI_SSR_GLOBAL_DATA, UNI_SSR_STORE, UNI_SSR_TITLE, UniBaseNode, UniCommentNode, UniElement, UniEvent, UniInputElement, UniNode, UniTextAreaElement, UniTextNode, WEB_INVOKE_APPSERVICE, WXS_MODULES, WXS_PROTOCOL, addFont, cache, cacheStringFunction, callOptions, createRpx2Unit, createUniEvent, debounce, decode, decodedQuery, defaultRpx2Unit, formatDateTime, formatLog, getCustomDataset, getEnvLocale, getLen, getValueByDataPath, initCustomDataset, invokeArrayFns, isBuiltInComponent, isCustomElement, isNativeTag, isRootHook, isServiceCustomElement, isServiceNativeTag, normalizeDataset, normalizeEventType, normalizeTarget, once, parseEventName, parseQuery, parseUrl, passive, plusReady, removeLeadingSlash, resolveOwnerEl, resolveOwnerVm, sanitise, scrollTo, stringifyQuery, updateElementStyle }; diff --git a/packages/uni-shared/src/vdom/Node.ts b/packages/uni-shared/src/vdom/Node.ts index d58f25077bffb17b5073c09fcae0592dc3dcc784..e02c680e0de4cf2f7e5a2951f1a9c3f7df2709d3 100644 --- a/packages/uni-shared/src/vdom/Node.ts +++ b/packages/uni-shared/src/vdom/Node.ts @@ -275,6 +275,7 @@ export const ATTR_INNER_HTML = 'innerHTML' export const ATTR_TEXT_CONTENT = 'textContent' export const ATTR_V_SHOW = '.vShow' export const ATTR_V_OWNER_ID = '.vOwnerId' +export const ATTR_V_RENDERJS = '.vRenderjs' export const ATTR_CHANGE_PREFIX = 'change:' export class UniBaseNode extends UniNode { diff --git a/packages/uni-shared/src/vdom/index.ts b/packages/uni-shared/src/vdom/index.ts index 990d33596187fce23262c10837a6f9d63c72131c..7b098b3407abcea18816b09628346e879a6ee8c7 100644 --- a/packages/uni-shared/src/vdom/index.ts +++ b/packages/uni-shared/src/vdom/index.ts @@ -14,6 +14,7 @@ export { ATTR_TEXT_CONTENT, ATTR_V_SHOW, ATTR_V_OWNER_ID, + ATTR_V_RENDERJS, ATTR_CHANGE_PREFIX, NODE_TYPE_PAGE, NODE_TYPE_ELEMENT, diff --git a/packages/uni-shared/src/vue.ts b/packages/uni-shared/src/vue.ts index 99cb9fbdaff6a562f0e36b78ef34ed41093efb43..fc55dc58cd47f1f18ad7a51042a5ca83163dc676 100644 --- a/packages/uni-shared/src/vue.ts +++ b/packages/uni-shared/src/vue.ts @@ -1,4 +1,4 @@ -import { ComponentInternalInstance } from 'vue' +import { ComponentInternalInstance, VNode } from 'vue' import { hyphenate } from '@vue/shared' import { isBuiltInComponent } from './tags' @@ -15,3 +15,26 @@ export function resolveOwnerVm(vm: ComponentInternalInstance) { } return vm.proxy! } + +function isElement(el: Element) { + // Element + return el.nodeType === 1 +} + +export function resolveOwnerEl(instance: ComponentInternalInstance) { + const { vnode } = instance + if (isElement(vnode.el as Element)) { + return vnode.el + } + const { subTree } = instance + // ShapeFlags.ARRAY_CHILDREN = 1<<4 + if (subTree.shapeFlag & 16) { + const elemVNode = (subTree.children as VNode[]).find((vnode) => + isElement(vnode.el as Element) + ) + if (elemVNode) { + return elemVNode.el + } + } + return vnode.el +}