1
- import { VNode , ComponentPublicInstance } from 'vue'
1
+ import {
2
+ ComponentPublicInstance ,
3
+ VNode ,
4
+ VNodeArrayChildren ,
5
+ VNodeNormalizedChildren
6
+ } from 'vue'
2
7
import { FindAllComponentsSelector } from '../types'
3
8
import { matchName } from './matchName'
4
9
@@ -28,26 +33,55 @@ function matches(node: VNode, selector: FindAllComponentsSelector): boolean {
28
33
return false
29
34
}
30
35
36
+ /**
37
+ * Filters out the null, undefined and primitive values,
38
+ * to only keep VNode and VNodeArrayChildren values
39
+ * @param value
40
+ */
41
+ function nodesAsObject < Node > (
42
+ value :
43
+ | string
44
+ | number
45
+ | boolean
46
+ | VNodeArrayChildren
47
+ | VNode
48
+ | null
49
+ | undefined
50
+ | void
51
+ ) : value is VNodeArrayChildren | VNode {
52
+ return ! ! value && typeof value === 'object'
53
+ }
54
+
31
55
/**
32
56
* Collect all children
33
57
* @param nodes
34
58
* @param children
35
59
*/
36
- function aggregateChildren ( nodes , children ) {
60
+ function aggregateChildren ( nodes : VNode [ ] , children : VNodeNormalizedChildren ) {
37
61
if ( children && Array . isArray ( children ) ) {
38
- ; [ ...children ] . reverse ( ) . forEach ( ( n : VNode ) => {
39
- nodes . unshift ( n )
62
+ const reversedNodes = [ ...children ] . reverse ( ) . filter ( nodesAsObject )
63
+ reversedNodes . forEach ( ( node : VNodeArrayChildren | VNode ) => {
64
+ if ( Array . isArray ( node ) ) {
65
+ aggregateChildren ( nodes , node )
66
+ } else {
67
+ nodes . unshift ( node )
68
+ }
40
69
} )
41
70
}
42
71
}
43
72
44
- function findAllVNodes ( vnode : VNode , selector : any ) : VNode [ ] {
45
- const matchingNodes = [ ]
46
- const nodes = [ vnode ]
73
+ function findAllVNodes (
74
+ vnode : VNode ,
75
+ selector : FindAllComponentsSelector
76
+ ) : VNode [ ] {
77
+ const matchingNodes : VNode [ ] = [ ]
78
+ const nodes : VNode [ ] = [ vnode ]
47
79
while ( nodes . length ) {
48
- const node = nodes . shift ( )
80
+ const node = nodes . shift ( ) !
49
81
aggregateChildren ( nodes , node . children )
50
- aggregateChildren ( nodes , node . component ?. subTree . children )
82
+ if ( node . component ) {
83
+ aggregateChildren ( nodes , node . component . subTree . children )
84
+ }
51
85
if ( matches ( node , selector ) ) {
52
86
matchingNodes . push ( node )
53
87
}
@@ -56,8 +90,11 @@ function findAllVNodes(vnode: VNode, selector: any): VNode[] {
56
90
return matchingNodes
57
91
}
58
92
59
- export function find ( root : VNode , selector : any ) : ComponentPublicInstance [ ] {
93
+ export function find (
94
+ root : VNode ,
95
+ selector : FindAllComponentsSelector
96
+ ) : ComponentPublicInstance [ ] {
60
97
return findAllVNodes ( root , selector ) . map (
61
- ( vnode : VNode ) => vnode . component . proxy
98
+ ( vnode : VNode ) => vnode . component ! . proxy !
62
99
)
63
100
}
0 commit comments