Skip to content

Commit

Permalink
[optimize]
Browse files Browse the repository at this point in the history
  • Loading branch information
CommanderXL committed Jan 20, 2025
1 parent 64853bb commit c7d477d
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 76 deletions.
65 changes: 36 additions & 29 deletions packages/core/src/platform/builtInMixins/relationsMixin.ios.js
Original file line number Diff line number Diff line change
@@ -1,48 +1,55 @@
import { MOUNTED, BEFOREUNMOUNT } from '../../core/innerLifecycle'
import { BEFORECREATE, MOUNTED, BEFOREUNMOUNT } from '../../core/innerLifecycle'

const relationTypeMap = {
parent: 'child',
ancestor: 'descendant'
}

export default function relationsMixin (mixinType) {
if (mixinType === 'component') {
return {
[BEFORECREATE] () {
this.__relationNodesMap = {}
},
[MOUNTED] () {
if (this.__relations) {
this.__mpxExecRelations('linked')
}
this.__mpxExecRelations('linked')
},
[BEFOREUNMOUNT] () {
if (this.__relations) {
this.__mpxExecRelations('unlinked')
this.__relations = {}
}
if (this.__relationNodesMap) {
this.__relationNodesMap = {}
}
this.__mpxExecRelations('unlinked')
this.__relationNodesMap = {}
},
methods: {
getRelationNodes (path) {
return this.__relationNodesMap?.[path] || null
return this.__relationNodesMap[path] || null
},
__mpxExecRelations (type) {
const relations = this.__relations
Object.keys(relations).forEach(path => {
const { target, targetRelation, relation } = relations[path]
const currentPath = this.__componentPath
if (type === 'linked') {
this.__mpxLinkRelationNodes(target, currentPath)
} else if (type === 'unlinked') {
this.__mpxRemoveRelationNodes(target, currentPath)
}
if (typeof targetRelation[type] === 'function') {
targetRelation[type].call(target, this)
}
if (typeof relation[type] === 'function') {
relation[type].call(this, target)
const relations = this.__mpxProxy.options.relations
const relationContext = this.__relation
const currentPath = this.__componentPath
Object.keys(relations).forEach((path) => {
const relation = relations[path]
const relationType = relation.type
if ((relationType === 'parent' || relationType === 'ancestor') && relationContext[path]) {
const target = relationContext[path]
const targetRelation = target.__mpxProxy.options.relations?.[currentPath]
if (targetRelation && targetRelation.type === relationTypeMap[relationType] && target.__componentPath === path) {
if (type === 'linked') {
this.__mpxLinkRelationNodes(target, currentPath)
} else if (type === 'unlinked') {
this.__mpxRemoveRelationNodes(target, currentPath)
}
if (typeof targetRelation[type] === 'function') {
targetRelation[type].call(target, this)
}
if (typeof relation[type] === 'function') {
relation[type].call(this, target)
}
this.__relationNodesMap[path] = [target]
}
}
})
},
__mpxLinkRelationNodes (target, path) {
if (!target.__relationNodesMap) {
target.__relationNodesMap = {}
}
target.__relationNodesMap[path] = target.__relationNodesMap[path] || [] // 父级绑定子级
target.__relationNodesMap[path].push(this)
},
Expand Down
66 changes: 19 additions & 47 deletions packages/core/src/platform/patch/getDefaultOptions.ios.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import * as ReactNative from 'react-native'
import { ReactiveEffect } from '../../observer/effect'
import { watch } from '../../observer/watch'
import { reactive, set, del } from '../../observer/reactive'
import { hasOwn, isFunction, noop, isObject, isArray, getByPath, collectDataset, hump2dash, dash2hump, callWithErrorHandling, wrapMethodsWithErrorHandling, isEmptyObject } from '@mpxjs/utils'
import { hasOwn, isFunction, noop, isObject, isArray, getByPath, collectDataset, hump2dash, dash2hump, callWithErrorHandling, wrapMethodsWithErrorHandling } from '@mpxjs/utils'
import MpxProxy from '../../core/proxy'
import { BEFOREUPDATE, ONLOAD, UPDATED, ONSHOW, ONHIDE, ONRESIZE, REACTHOOKSEXEC } from '../../core/innerLifecycle'
import mergeOptions from '../../core/mergeOptions'
Expand Down Expand Up @@ -193,7 +193,7 @@ const instanceProto = {
}
}

function createInstance ({ propsRef, type, rawOptions, currentInject, validProps, components, pageId, intersectionCtx, relationInfo }) {
function createInstance ({ propsRef, type, rawOptions, currentInject, validProps, components, pageId, intersectionCtx, relation }) {
const instance = Object.create(instanceProto, {
dataset: {
get () {
Expand Down Expand Up @@ -256,9 +256,13 @@ function createInstance ({ propsRef, type, rawOptions, currentInject, validProps
})
}

if (!isEmptyObject(relationInfo.relations)) {
instance.__relations = relationInfo.relations
instance.__relationNodesMap = relationInfo.relationNodesMap
if (relation) {
Object.defineProperty(instance, '__relation', {
get () {
return relation
},
enumerable: false
})
}

// bind this & assign methods
Expand Down Expand Up @@ -393,85 +397,53 @@ const RelationsContext = createContext(null)
const checkRelation = (options) => {
const relations = options.relations || {}
let hasDescendantRelation = false
const ancestorRelations = {}
let hasAncestorRelation = false
Object.keys(relations).forEach((path) => {
const relation = relations[path]
const type = relation.type
if (['child', 'descendant'].includes(type)) {
hasDescendantRelation = true
} else if (['parent', 'ancestor'].includes(type)) {
ancestorRelations[path] = relation
hasAncestorRelation = true
}
})
return {
hasDescendantRelation,
ancestorRelations
hasAncestorRelation
}
}

const provideRelation = (instance, relation) => {
const componentPath = instance.__componentPath
if (relation) {
if (!relation[componentPath]) {
relation[componentPath] = instance
}
return relation
return Object.assign({}, relation, { [componentPath]: instance })
} else {
return {
[componentPath]: instance
}
}
}

const relationTypeMap = {
parent: 'child',
ancestor: 'descendant'
}

const collectRelations = (ancestorRelations, relationMap, componentPath = '') => {
const relations = {}
const relationNodesMap = {}
Object.keys(ancestorRelations).forEach(path => {
const relation = ancestorRelations[path]
const type = relation.type
if (relationMap[path]) {
const target = relationMap[path]
const targetRelation = target.__mpxProxy.options.relations?.[componentPath]
if (targetRelation && targetRelation.type === relationTypeMap[type] && target.__componentPath === path) {
relations[path] = {
target,
targetRelation,
relation
}
relationNodesMap[path] = [target]
}
}
})

return {
relations,
relationNodesMap
}
}

export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {
rawOptions = mergeOptions(rawOptions, type, false)
const components = Object.assign({}, rawOptions.components, currentInject.getComponents())
const validProps = Object.assign({}, rawOptions.props, rawOptions.properties)
const { hasDescendantRelation, ancestorRelations } = checkRelation(rawOptions)
const { hasDescendantRelation, hasAncestorRelation } = checkRelation(rawOptions)
if (rawOptions.methods) rawOptions.methods = wrapMethodsWithErrorHandling(rawOptions.methods)
const defaultOptions = memo(forwardRef((props, ref) => {
const instanceRef = useRef(null)
const propsRef = useRef(null)
const intersectionCtx = useContext(IntersectionObserverContext)
const pageId = useContext(RouteContext)
const relation = useContext(RelationsContext)
const relationInfo = collectRelations(ancestorRelations, relation, currentInject.componentPath)
let relation = null
if (hasDescendantRelation || hasAncestorRelation) {
relation = useContext(RelationsContext)
}
propsRef.current = props
let isFirst = false
if (!instanceRef.current) {
isFirst = true
instanceRef.current = createInstance({ propsRef, type, rawOptions, currentInject, validProps, components, pageId, intersectionCtx, relationInfo })
instanceRef.current = createInstance({ propsRef, type, rawOptions, currentInject, validProps, components, pageId, intersectionCtx, relation })
}
const instance = instanceRef.current
useImperativeHandle(ref, () => {
Expand Down

0 comments on commit c7d477d

Please sign in to comment.