From 98a5fea7e23b96de7b92a708b1ead27f009dea70 Mon Sep 17 00:00:00 2001 From: qiang Date: Mon, 10 Oct 2022 20:39:17 +0800 Subject: [PATCH] fix(mp): $refs use cache --- src/platforms/mp-jd/runtime/wrapper/util.js | 86 ------------------- .../mp-toutiao/runtime/wrapper/util.js | 24 +----- .../mp-weixin/runtime/wrapper/util.js | 25 +++++- 3 files changed, 25 insertions(+), 110 deletions(-) delete mode 100644 src/platforms/mp-jd/runtime/wrapper/util.js diff --git a/src/platforms/mp-jd/runtime/wrapper/util.js b/src/platforms/mp-jd/runtime/wrapper/util.js deleted file mode 100644 index 7fb3ce5b6..000000000 --- a/src/platforms/mp-jd/runtime/wrapper/util.js +++ /dev/null @@ -1,86 +0,0 @@ -export const mocks = ['__route__', '__wxExparserNodeId__', '__wxWebviewId__'] - -export function findVmByVueId (vm, vuePid) { - const $children = vm.$children - // 优先查找直属(反向查找:https://github.com/dcloudio/uni-app/issues/1200) - for (let i = $children.length - 1; i >= 0; i--) { - const childVm = $children[i] - if (childVm.$scope._$vueId === vuePid) { - return childVm - } - } - // 反向递归查找 - let parentVm - for (let i = $children.length - 1; i >= 0; i--) { - parentVm = findVmByVueId($children[i], vuePid) - if (parentVm) { - return parentVm - } - } -} - -export function initBehavior (options) { - return Behavior(options) -} - -export function isPage () { - return !!this.route -} - -export function initRelation (detail) { - this.triggerEvent('__l', detail) -} - -function selectAllComponents (mpInstance, selector, $refs) { - const components = mpInstance.selectAllComponents(selector) - components.forEach(component => { - const ref = component.dataset.ref - $refs[ref] = component.$vm || component - if (__PLATFORM__ === 'mp-weixin') { - if (component.dataset.vueGeneric === 'scoped') { - component.selectAllComponents('.scoped-ref').forEach(scopedComponent => { - selectAllComponents(scopedComponent, selector, $refs) - }) - } - } - }) -} - -export function initRefs (vm) { - const mpInstance = vm.$scope - Object.defineProperty(vm, '$refs', { - get () { - const $refs = {} - selectAllComponents(mpInstance, '.vue-ref', $refs) - // TODO 暂不考虑 for 中的 scoped - const forComponents = mpInstance.selectAllComponents('.vue-ref-in-for') - forComponents.forEach(component => { - const ref = component.dataset.ref - if (!$refs[ref]) { - $refs[ref] = [] - } - $refs[ref].push(component.$vm || component) - }) - return $refs - } - }) -} - -export function handleLink (event) { - const { - vuePid, - vueOptions - } = event.detail || event.value // detail 是微信,value 是百度(dipatch) - - let parentVm - - if (vuePid) { - parentVm = findVmByVueId(this.$vm, vuePid) - } - - if (!parentVm) { - parentVm = this.$vm - } - - vueOptions.parent = parentVm -} diff --git a/src/platforms/mp-toutiao/runtime/wrapper/util.js b/src/platforms/mp-toutiao/runtime/wrapper/util.js index 44aadf0c4..6169f4313 100644 --- a/src/platforms/mp-toutiao/runtime/wrapper/util.js +++ b/src/platforms/mp-toutiao/runtime/wrapper/util.js @@ -1,5 +1,6 @@ import { - findVmByVueId + findVmByVueId, + initRefs as initRefsBase } from '../../../mp-weixin/runtime/wrapper/util' export const mocks = ['__route__', '__webviewId__', '__nodeid__', '__nodeId__'] @@ -13,26 +14,7 @@ export function initRefs (vm) { /* eslint-disable no-undef */ const minorVersion = parseInt(tt.getSystemInfoSync().SDKVersion.split('.')[1]) if (minorVersion > 16) { - Object.defineProperty(vm, '$refs', { - get () { - const $refs = {} - // mpInstance 销毁后 selectAllComponents 取值为 null - const components = mpInstance.selectAllComponents('.vue-ref') || [] - components.forEach(component => { - const ref = component.dataset.ref - $refs[ref] = component.$vm || component - }) - const forComponents = mpInstance.selectAllComponents('.vue-ref-in-for') || [] - forComponents.forEach(component => { - const ref = component.dataset.ref - if (!$refs[ref]) { - $refs[ref] = [] - } - $refs[ref].push(component.$vm || component) - }) - return $refs - } - }) + initRefsBase(vm) } else { mpInstance.selectAllComponents('.vue-ref', (components) => { components.forEach(component => { diff --git a/src/platforms/mp-weixin/runtime/wrapper/util.js b/src/platforms/mp-weixin/runtime/wrapper/util.js index 34abec9b1..877a1e45c 100644 --- a/src/platforms/mp-weixin/runtime/wrapper/util.js +++ b/src/platforms/mp-weixin/runtime/wrapper/util.js @@ -32,7 +32,7 @@ export function initRelation (detail) { } function selectAllComponents (mpInstance, selector, $refs) { - const components = mpInstance.selectAllComponents(selector) + const components = mpInstance.selectAllComponents(selector) || [] components.forEach(component => { const ref = component.dataset.ref $refs[ref] = component.$vm || component @@ -46,14 +46,33 @@ function selectAllComponents (mpInstance, selector, $refs) { }) } +export function syncRefs (refs, newRefs) { + const oldKeys = new Set(...Object.keys(refs)) + const newKeys = Object.keys(newRefs) + newKeys.forEach(key => { + const oldValue = refs[key] + const newValue = newRefs[key] + if (Array.isArray(oldValue) && Array.isArray(newValue) && oldValue.length === newValue.length && newValue.every(value => oldValue.includes(value))) { + return + } + refs[key] = newValue + oldKeys.delete(key) + }) + oldKeys.forEach(key => { + delete refs[key] + }) + return refs +} + export function initRefs (vm) { const mpInstance = vm.$scope + const refs = {} Object.defineProperty(vm, '$refs', { get () { const $refs = {} selectAllComponents(mpInstance, '.vue-ref', $refs) // TODO 暂不考虑 for 中的 scoped - const forComponents = mpInstance.selectAllComponents('.vue-ref-in-for') + const forComponents = mpInstance.selectAllComponents('.vue-ref-in-for') || [] forComponents.forEach(component => { const ref = component.dataset.ref if (!$refs[ref]) { @@ -61,7 +80,7 @@ export function initRefs (vm) { } $refs[ref].push(component.$vm || component) }) - return $refs + return syncRefs(refs, $refs) } }) } -- GitLab