提交 98a5fea7 编写于 作者: Q qiang

fix(mp): $refs use cache

上级 cdbb3031
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
}
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 => {
......
......@@ -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)
}
})
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册