diff --git a/src/platforms/app-plus/helpers/util.js b/src/platforms/app-plus/helpers/util.js new file mode 100644 index 0000000000000000000000000000000000000000..6c22c286d7d7270452ca0bdb2d90d3c0f979c929 --- /dev/null +++ b/src/platforms/app-plus/helpers/util.js @@ -0,0 +1,15 @@ +export function generateId (vm, parent) { + if (!vm.$parent) { + return '-1' + } + const vnode = vm.$vnode + const context = vnode.context + // slot 内的组件,需要补充 context 的 id,否则可能与内部组件索引值一致,导致 id 冲突 + if (context && context !== parent && context._$id) { + if (process.env.NODE_ENV !== 'production') { + console.log('generateId:' + context._$id + ';' + parent._$id + ',' + vnode.data.attrs._i) + } + return context._$id + ';' + parent._$id + ',' + vnode.data.attrs._i + } + return parent._$id + ',' + vnode.data.attrs._i +} diff --git a/src/platforms/app-plus/service/framework/plugins/data.js b/src/platforms/app-plus/service/framework/plugins/data.js index eea6e6ec654d5c4da95d4da857c7097f0e154a83..fcbbc6638fcda3705cea1331a44fbe3a7f938dda 100644 --- a/src/platforms/app-plus/service/framework/plugins/data.js +++ b/src/platforms/app-plus/service/framework/plugins/data.js @@ -21,7 +21,11 @@ import { B_CLASS, B_STYLE, S_CLASS -} from '../../constants' +} from '../../constants' + +import { + generateId +} from '../../../helpers/util' import { diff @@ -57,10 +61,7 @@ export function initData (Vue) { if (!this._$vd) { return } - // TODO 自定义组件中的 slot 数据采集是在组件内部,导致所在 context 中无法获取到差量数据 - // 如何保证每个 vm 数据有变动,就加入 diff 中呢? - // 每次变化,可能触发多次 beforeUpdate,updated - // 子组件 updated 时,可能会增加父组件的 diffData,如 slot 等情况 + diff(this._$newData, this._$data, this._$vdUpdatedData) this._$data = JSON.parse(JSON.stringify(this._$newData)) // setTimeout 一下再 nextTick( 直接 nextTick 的话,会紧接着该 updated 做 flush,导致父组件 updated 数据被丢弃) @@ -87,11 +88,7 @@ export function initData (Vue) { this._$vdomSync = new VDomSync(this.$options.pageId, this.$options.pagePath, this) } if (this._$vd) { - if (!this.$parent) { - this._$id = '-1' - } else { - this._$id = this.$parent._$id + ',' + this.$vnode.data.attrs._i - } + this._$id = generateId(this, this.$parent) this._$vd.addVm(this) this._$vdMountedData = Object.create(null) this._$setData(MOUNTED_DATA, this._$vdMountedData) diff --git a/src/platforms/app-plus/service/framework/plugins/vdom-sync.js b/src/platforms/app-plus/service/framework/plugins/vdom-sync.js index e140fe86716b7f14a911185ce15ab08d42add539..d1f81362240cc04601d318f58cd983609ba63510 100644 --- a/src/platforms/app-plus/service/framework/plugins/vdom-sync.js +++ b/src/platforms/app-plus/service/framework/plugins/vdom-sync.js @@ -153,16 +153,12 @@ export class VDomSync { removeElement (elm) { const elmIndex = this.elements.indexOf(elm) if (elmIndex === -1) { - return console.error(`removeElement[${elm.cid}][${elm.nid}] not found`) - } - this.elements.splice(elmIndex, 1) - } - - removeElementByCid (cid) { - if (!cid) { + if (process.env.NODE_ENV !== 'production') { + console.error(`removeElement[${elm.cid}][${elm.nid}] not found`) + } return } - this.elements = this.elements.filter(elm => elm.cid !== cid) + this.elements.splice(elmIndex, 1) } push (type, cid, data, options) { diff --git a/src/platforms/app-plus/view/framework/plugins/event.js b/src/platforms/app-plus/view/framework/plugins/event.js index a7ddc29845b641faba844fc9fc15e0686398c2e5..69a676270687e9a96c4939f7faf9efe2032d81aa 100644 --- a/src/platforms/app-plus/view/framework/plugins/event.js +++ b/src/platforms/app-plus/view/framework/plugins/event.js @@ -29,10 +29,11 @@ export function initEvent (Vue) { } const $event = this.$handleEvent($vueEvent) - const cid = this._$id - // 当自定义组件根节点触发事件时,nid 始终为 0 - const currentTarget = $vueEvent.$origCurrentTarget || $vueEvent.currentTarget - const nid = currentTarget === this.$el ? 0 : $event.options.nid + const cid = this._$id + + const currentTarget = $vueEvent.$origCurrentTarget || $vueEvent.currentTarget + // 当自定义组件根节点触发事件时,nid 补充前缀,避免与组件内部 nid 冲突(根组件page不需要) + const nid = ((currentTarget === this.$el && this.mpType !== 'page') ? 'r-' : '') + $event.options.nid if (typeof nid === 'undefined') { return console.error(`[${cid}] nid not found`) } @@ -42,7 +43,7 @@ export function initEvent (Vue) { delete $event.mp delete $event.preventDefault delete $event.stopPropagation - delete $event.options + delete $event.options delete $event.$origCurrentTarget // 实时发送,延迟的话,会导致 touch 类事件被合并,影响实际业务逻辑,比如 touchstart 中修改变量为 true,touchend 修改为 false vd.sendUIEvent(cid, nid, $event) diff --git a/src/platforms/app-plus/view/framework/plugins/vdom-sync.js b/src/platforms/app-plus/view/framework/plugins/vdom-sync.js index 262fda2c31b0119c5ab15e5d9a4813d95beac958..d046ecc1db9739590459674d445e2eb3118f9b1b 100644 --- a/src/platforms/app-plus/view/framework/plugins/vdom-sync.js +++ b/src/platforms/app-plus/view/framework/plugins/vdom-sync.js @@ -3,11 +3,15 @@ import { UI_EVENT } from '../../../constants' -function findParentCid (vm) { +import { + generateId +} from '../../../helpers/util' + +function findParent (vm) { let parent = vm.$parent while (parent) { if (parent._$id) { - return parent._$id + return parent } parent = parent.$parent } @@ -30,11 +34,7 @@ export class VDomSync { } initVm (vm) { - if (!vm.$parent) { - vm._$id = '-1' - } else { - vm._$id = findParentCid(vm) + ',' + vm.$vnode.data.attrs._i - } + vm._$id = generateId(vm, findParent(vm)) let vData = this.addBatchVData[vm._$id] if (!vData) { console.error('cid unmatched', vm)