-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(tabs): support tab-pane
lazy load
#1423
Conversation
This pull request is being automatically deployed with Vercel (learn more). 🔍 Inspect: https://vercel.com/tusimple/naive-ui/6UxV3JF1PSn4wciiPLVqUCEo4ZeP |
I will add test cases and docs later. |
Codecov Report
@@ Coverage Diff @@
## main #1423 +/- ##
==========================================
+ Coverage 52.89% 53.04% +0.14%
==========================================
Files 534 534
Lines 13354 13362 +8
Branches 3815 3819 +4
==========================================
+ Hits 7064 7088 +24
+ Misses 5164 5145 -19
- Partials 1126 1129 +3
Continue to review full report at Codecov.
|
src/tabs/tests/Tabs.spec.ts
Outdated
slots: { | ||
default: () => [ | ||
h( | ||
NTabPane, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change Tabs.spec.ts
to Tabs.spec.tsx
to make code tight.
src/tabs/src/Tabs.tsx
Outdated
return tabPaneVNodes.filter((vNode) => { | ||
const props = vNode.props as { | ||
name: string | number | ||
displayDirective: 'show' | 'if' | undefined | ||
'display-directive': 'show' | 'if' | undefined | ||
active: boolean | ||
displayDirective: TabPaneProps['displayDirective'] | ||
'display-directive': TabPaneProps['displayDirective'] | ||
} | ||
const useVShow = displayDirective === 'show' || _displayDirective === 'show' | ||
const show = value === name | ||
const active = (props.active = props.name === value) | ||
if (vNode.key !== undefined) { | ||
vNode.key = name | ||
} | ||
if (useVShow) { | ||
children.push(withDirectives(vNode, [[vShow, show]])) | ||
} else if (show) { | ||
children.push(vNode) | ||
vNode.key = props.name | ||
} | ||
return ( | ||
active || | ||
(props.displayDirective !== 'if' && props['display-directive'] !== 'if') | ||
) | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
active
is not a good way to implement the feature.
If you controll whether to show the tab inside TabPane
component. Then if there are 10 tabs, there would be 10 TabPane
vnode in the first rendering. It would not be a clean implementaion.
The corrrect way is to modify filterMapTabPanes
method.
- Record activated tab name in a set
- Determine whether to show the tab pane in
filterMapTabPanes
by the set - If set has the name, push it in children, else do nothing. Use
v-show
for the children in lazy mode.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I also had this concern before, which would increase the number of vnode
for no reason, so the if
is filtered out in subsequent push.
I performed a secondary process in the tab-pane
, because I think the better way to save the active state is in the respective components. Maybe I think it will have more complicated usage scenarios so I do so.
I will re-investigate the feature and perform performance testing, and push a better way to deal with it.
src/tabs/src/Tabs.tsx
Outdated
@@ -137,6 +144,7 @@ export default defineComponent({ | |||
compitableValueRef, | |||
uncontrolledValueRef | |||
) | |||
const renderedNames = reactive(new Set<NonNullable<TabPaneProps['name']>>()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
renderedNamesRef
😥看来是我把 |
加个开发者群么?你可以加一下钉钉二群然后 @ 群主 |
close #1374.