From 2784d6615d6f20b6d6811f5d6b4c3f314341caad Mon Sep 17 00:00:00 2001 From: Evan You Date: Tue, 6 Apr 2021 16:51:11 -0400 Subject: [PATCH] wip: $children compat --- packages/runtime-core/src/compat/children.ts | 28 +++++++++++++++++++ .../runtime-core/src/compat/deprecations.ts | 8 ++++++ packages/runtime-core/src/compat/instance.ts | 4 ++- 3 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 packages/runtime-core/src/compat/children.ts diff --git a/packages/runtime-core/src/compat/children.ts b/packages/runtime-core/src/compat/children.ts new file mode 100644 index 00000000..c444d2ee --- /dev/null +++ b/packages/runtime-core/src/compat/children.ts @@ -0,0 +1,28 @@ +import { ShapeFlags } from '@vue/shared/src' +import { ComponentInternalInstance } from '../component' +import { ComponentPublicInstance } from '../componentPublicInstance' +import { VNode } from '../vnode' +import { DeprecationTypes, warnDeprecation } from './deprecations' + +export function getInstanceChildren( + instance: ComponentInternalInstance +): ComponentPublicInstance[] { + __DEV__ && warnDeprecation(DeprecationTypes.INSTANCE_CHILDREN) + const root = instance.subTree + const children: ComponentPublicInstance[] = [] + if (root) { + walk(root, children) + } + return children +} + +function walk(vnode: VNode, children: ComponentPublicInstance[]) { + if (vnode.component) { + children.push(vnode.component.proxy!) + } else if (vnode.shapeFlag & ShapeFlags.ARRAY_CHILDREN) { + const vnodes = vnode.children as VNode[] + for (let i = 0; i < vnodes.length; i++) { + walk(vnodes[i], children) + } + } +} diff --git a/packages/runtime-core/src/compat/deprecations.ts b/packages/runtime-core/src/compat/deprecations.ts index f71d77ff..a371649c 100644 --- a/packages/runtime-core/src/compat/deprecations.ts +++ b/packages/runtime-core/src/compat/deprecations.ts @@ -20,6 +20,7 @@ export const enum DeprecationTypes { INSTANCE_DESTROY, INSTANCE_EVENT_EMITTER, INSTANCE_EVENT_HOOKS, + INSTANCE_CHILDREN, OPTIONS_DATA_FN, OPTIONS_DATA_MERGE, @@ -148,6 +149,13 @@ const deprecations: Record = { link: `https://v3.vuejs.org/api/composition-api.html#lifecycle-hooks` }, + [DeprecationTypes.INSTANCE_CHILDREN]: { + message: + `vm.$children has been removed. Consider refactoring your logic ` + + `to avoid relying on direct access to child components.`, + link: `https://v3.vuejs.org/guide/migration/children.html` + }, + [DeprecationTypes.OPTIONS_DATA_FN]: { message: `The "data" option can no longer be a plain object. ` + diff --git a/packages/runtime-core/src/compat/instance.ts b/packages/runtime-core/src/compat/instance.ts index a7158add..557706f2 100644 --- a/packages/runtime-core/src/compat/instance.ts +++ b/packages/runtime-core/src/compat/instance.ts @@ -1,5 +1,6 @@ import { extend, NOOP } from '@vue/shared' import { PublicPropertiesMap } from '../componentPublicInstance' +import { getInstanceChildren } from './children' import { DeprecationTypes, warnDeprecation } from './deprecations' import { off, on, once } from './eventEmitter' @@ -33,6 +34,7 @@ export function installCompatInstanceProperties(map: PublicPropertiesMap) { }, $on: i => on.bind(null, i), $once: i => once.bind(null, i), - $off: i => off.bind(null, i) + $off: i => off.bind(null, i), + $children: getInstanceChildren } as PublicPropertiesMap) }