1- import { computed , ComputedRef , Ref , onUnmounted } from 'vue' ;
1+ import { computed , ComputedRef , Ref , onUnmounted , shallowRef , toRaw , toValue } from 'vue' ;
22import { IInnerTreeNode , ITreeNode , IUseCore , valueof } from './use-tree-types' ;
33import { generateInnerTree } from './utils' ;
44
@@ -10,8 +10,70 @@ const DEFAULT_CONFIG = {
1010export function useCore ( ) : ( data : Ref < IInnerTreeNode [ ] > ) => IUseCore {
1111 const nodeMap = new Map < string , IInnerTreeNode [ ] > ( ) ;
1212 return function useCoreFn ( data : Ref < IInnerTreeNode [ ] > ) : IUseCore {
13- const getLevel = ( node : IInnerTreeNode ) : number => {
14- return data . value . find ( ( item ) => item . id === node . id ) ?. level ;
13+ const hashTreeData = shallowRef < Record < string | number , IInnerTreeNode > > ( { } ) ;
14+
15+ const updateHashTreeData = ( ) => {
16+ hashTreeData . value = { } ;
17+ for ( let i = 0 ; i < data . value . length ; i ++ ) {
18+ const item = data . value [ i ] ;
19+ if ( hashTreeData . value [ item . id ] ) {
20+ console . error ( `节点id【${ item . id } 】重复` ) ;
21+ } else {
22+ hashTreeData . value [ item . id ] = item ;
23+ }
24+ }
25+ } ;
26+
27+ const getInnerNode = ( node : IInnerTreeNode | ITreeNode ) => {
28+ if ( ! node ) {
29+ return null ;
30+ }
31+ if ( node . id != undefined && hashTreeData . value [ node . id ] ) {
32+ return hashTreeData . value [ node . id ] ;
33+ }
34+ return null ;
35+ } ;
36+ const getLevel = ( node : IInnerTreeNode ) => {
37+ const innerNode = getInnerNode ( node ) ;
38+ if ( innerNode ) {
39+ return innerNode . level ;
40+ }
41+ return undefined ;
42+ } ;
43+
44+ const toggleChildNodeVisible = ( node : IInnerTreeNode , visible : boolean ) => {
45+ if ( ! node . childList ?. length ) {
46+ return ;
47+ }
48+ const nodeList = [ ...node . childList ] ;
49+ while ( nodeList . length ) {
50+ const item = nodeList . shift ( ) ;
51+ if ( item ) {
52+ item . showNode = visible ;
53+ if ( ( visible && item . expanded ) || ( ! visible && item . childNodeCount ) ) {
54+ const temp = item . childList || [ ] ;
55+ nodeList . push ( ...temp ) ;
56+ }
57+ }
58+ }
59+ } ;
60+
61+ const getInnerExpendedTree = ( ) : ComputedRef < IInnerTreeNode [ ] > => {
62+ return computed ( ( ) => {
63+ let excludeNodes : IInnerTreeNode [ ] = [ ] ;
64+ const result = [ ] ;
65+ for ( let i = 0 , len = data ?. value . length ; i < len ; i ++ ) {
66+ const item = data ?. value [ i ] ;
67+ if ( excludeNodes . map ( ( innerNode ) => innerNode . id ) . includes ( item . id ) ) {
68+ continue ;
69+ }
70+ if ( item . expanded !== true && ! item . isLeaf ) {
71+ excludeNodes = getChildren ( item ) ;
72+ }
73+ result . push ( item ) ;
74+ }
75+ return result ;
76+ } ) ;
1577 } ;
1678
1779 const getChildren = ( node : IInnerTreeNode , userConfig = DEFAULT_CONFIG ) : IInnerTreeNode [ ] => {
@@ -31,32 +93,17 @@ export function useCore(): (data: Ref<IInnerTreeNode[]>) => IUseCore {
3193 return cacheNode ;
3294 }
3395 }
34- const getInnerExpendedTree = ( ) : ComputedRef < IInnerTreeNode [ ] > => {
35- return computed ( ( ) => {
36- let excludeNodes : IInnerTreeNode [ ] = [ ] ;
37- const result = [ ] ;
38- for ( let i = 0 , len = data ?. value . length ; i < len ; i ++ ) {
39- const item = data ?. value [ i ] ;
40- if ( excludeNodes . map ( ( innerNode ) => innerNode . id ) . includes ( item . id ) ) {
41- continue ;
42- }
43- if ( item . expanded !== true && ! item . isLeaf ) {
44- excludeNodes = getChildren ( item ) ;
45- }
46- result . push ( item ) ;
47- }
48- return result ;
49- } ) ;
50- } ;
96+
5197 const result = [ ] ;
5298 const config = { ...DEFAULT_CONFIG , ...userConfig } ;
5399 const treeData = config . expanded ? getInnerExpendedTree ( ) : data ;
54100 const startIndex = treeData . value . findIndex ( ( item ) => item . id === node . id ) ;
101+ const nodeLevel = node . level ;
55102
56- for ( let i = startIndex + 1 ; i < treeData . value . length && getLevel ( node ) < treeData . value [ i ] . level ; i ++ ) {
103+ for ( let i = startIndex + 1 ; i < treeData . value . length && nodeLevel < treeData . value [ i ] . level ; i ++ ) {
57104 if ( config . recursive && ! treeData . value [ i ] . isHide ) {
58105 result . push ( treeData . value [ i ] ) ;
59- } else if ( getLevel ( node ) === treeData . value [ i ] . level - 1 && ! treeData . value [ i ] . isHide ) {
106+ } else if ( nodeLevel === treeData . value [ i ] . level - 1 && ! treeData . value [ i ] . isHide ) {
60107 result . push ( treeData . value [ i ] ) ;
61108 }
62109 }
@@ -70,26 +117,43 @@ export function useCore(): (data: Ref<IInnerTreeNode[]>) => IUseCore {
70117 nodeMap . clear ( ) ;
71118 } ;
72119
73- const getParent = ( node : IInnerTreeNode ) : IInnerTreeNode => {
74- return data . value . find ( ( item ) => item . id === node . parentId ) ;
120+ const getParent = ( node : IInnerTreeNode ) => {
121+ if ( node . parentId !== undefined ) {
122+ return hashTreeData . value [ node . parentId ] ;
123+ }
124+ return undefined ;
125+ } ;
126+
127+ const getLastChild = ( node : IInnerTreeNode ) => {
128+ const children = getChildren ( node , { recursive : false } ) ;
129+ const lastChild = children [ children . length - 1 ] ;
130+ return lastChild ?. childNodeCount ? getLastChild ( lastChild ) : lastChild ;
75131 } ;
76132
133+ const getFlattenChildren = ( node : IInnerTreeNode ) => {
134+ const lastChild = getLastChild ( node ) ;
135+ const startPos = getIndex ( node ) + 1 ;
136+ const endPos = lastChild ? getIndex ( lastChild ) + 1 : startPos ;
137+ return data . value . slice ( startPos , endPos ) ;
138+ } ;
139+
140+ let showTreeList : ComputedRef < IInnerTreeNode [ ] > ;
141+
77142 const getExpendedTree = ( ) : ComputedRef < IInnerTreeNode [ ] > => {
78- return computed ( ( ) => {
79- let excludeNodes : IInnerTreeNode [ ] = [ ] ;
80- const result = [ ] ;
81- for ( let i = 0 , len = data ?. value . length ; i < len ; i ++ ) {
82- const item = data ?. value [ i ] ;
83- if ( excludeNodes . map ( ( node ) => node . id ) . includes ( item . id ) || item . isHide ) {
84- continue ;
85- }
86- if ( item . expanded !== true ) {
87- excludeNodes = getChildren ( item ) ;
143+ if ( showTreeList ) {
144+ return showTreeList ;
145+ }
146+ showTreeList = computed ( ( ) => {
147+ const res : IInnerTreeNode [ ] = [ ] ;
148+ const originDataVal = toValue ( data ) ;
149+ for ( const item of originDataVal ) {
150+ if ( ! item . isHide && item . showNode ) {
151+ res . push ( item ) ;
88152 }
89- result . push ( item ) ;
90153 }
91- return result ;
154+ return res ;
92155 } ) ;
156+ return showTreeList ;
93157 } ;
94158
95159 const getIndex = ( node : IInnerTreeNode ) : number => {
@@ -100,20 +164,27 @@ export function useCore(): (data: Ref<IInnerTreeNode[]>) => IUseCore {
100164 return data . value . findIndex ( ( item ) => item . id === node . id ) ;
101165 } ;
102166
103- const getNode = ( node : IInnerTreeNode ) : IInnerTreeNode => {
104- return data . value . find ( ( item ) => item . id === node . id ) ;
167+ const getNode = ( node : IInnerTreeNode | string | number ) => {
168+ if ( typeof node === 'string' || typeof node === 'number' ) {
169+ return hashTreeData . value [ node ] ;
170+ } else {
171+ return getInnerNode ( node ) ?? undefined ;
172+ }
105173 } ;
106174
107175 const setNodeValue = ( node : IInnerTreeNode , key : keyof IInnerTreeNode , value : valueof < IInnerTreeNode > ) : void => {
108176 clearNodeMap ( ) ;
109- if ( getIndex ( node ) !== - 1 ) {
110- data . value [ getIndex ( node ) ] [ key ] = value ;
177+ const innerNode = getInnerNode ( node ) ;
178+ if ( ! innerNode ) {
179+ return ;
111180 }
181+ innerNode [ key ] = value ;
112182 } ;
113183
114184 const setTree = ( newTree : ITreeNode [ ] ) : void => {
115185 clearNodeMap ( ) ;
116186 data . value = generateInnerTree ( newTree ) ;
187+ updateHashTreeData ( ) ;
117188 } ;
118189
119190 const getTree = ( ) => {
@@ -135,6 +206,10 @@ export function useCore(): (data: Ref<IInnerTreeNode[]>) => IUseCore {
135206 setNodeValue,
136207 setTree,
137208 getTree,
209+ updateHashTreeData,
210+ toggleChildNodeVisible,
211+ hashTreeData,
212+ getFlattenChildren,
138213 } ;
139214 } ;
140215}
0 commit comments