feat(IndexBar): add teleport prop (#8820)

This commit is contained in:
neverland 2021-06-07 19:31:40 +08:00 committed by GitHub
parent b2a090344f
commit 026a1094c5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 35 additions and 9 deletions

View File

@ -4,8 +4,10 @@ import {
computed, computed,
nextTick, nextTick,
PropType, PropType,
Teleport,
onMounted, onMounted,
CSSProperties, CSSProperties,
TeleportProps,
defineComponent, defineComponent,
ExtractPropTypes, ExtractPropTypes,
} from 'vue'; } from 'vue';
@ -49,6 +51,7 @@ export const INDEX_BAR_KEY = Symbol(name);
const props = { const props = {
sticky: truthProp, sticky: truthProp,
zIndex: [Number, String], zIndex: [Number, String],
teleport: [String, Object] as PropType<TeleportProps['to']>,
highlightColor: String, highlightColor: String,
stickyOffsetTop: { stickyOffsetTop: {
type: Number, type: Number,
@ -252,19 +255,27 @@ export default defineComponent({
} }
}; };
const renderSidebar = () => (
<div
class={bem('sidebar')}
style={sidebarStyle.value}
onClick={onClickSidebar}
onTouchstart={touch.start}
onTouchmove={onTouchMove}
>
{renderIndexes()}
</div>
);
useExpose({ scrollTo }); useExpose({ scrollTo });
return () => ( return () => (
<div ref={root} class={bem()}> <div ref={root} class={bem()}>
<div {props.teleport ? (
class={bem('sidebar')} <Teleport to={props.teleport}>{renderSidebar()}</Teleport>
style={sidebarStyle.value} ) : (
onClick={onClickSidebar} renderSidebar()
onTouchstart={touch.start} )}
onTouchmove={onTouchMove}
>
{renderIndexes()}
</div>
{slots.default?.()} {slots.default?.()}
</div> </div>
); );

View File

@ -76,6 +76,7 @@ export default {
| sticky | Whether to enable anchor sticky top | _boolean_ | `true` | | sticky | Whether to enable anchor sticky top | _boolean_ | `true` |
| sticky-offset-top | Anchor offset top when sticky | _number_ | `0` | | sticky-offset-top | Anchor offset top when sticky | _number_ | `0` |
| highlight-color | Index character highlight color | _string_ | `#ee0a24` | - | | highlight-color | Index character highlight color | _string_ | `#ee0a24` | - |
| teleport `v3.0.19` | Specifies a target element where IndexBar will be mounted | _string \| Element_ | - |
### IndexAnchor Props ### IndexAnchor Props

View File

@ -80,6 +80,7 @@ export default {
| sticky | 是否开启锚点自动吸顶 | _boolean_ | `true` | | sticky | 是否开启锚点自动吸顶 | _boolean_ | `true` |
| sticky-offset-top | 锚点自动吸顶时与顶部的距离 | _number_ | `0` | | sticky-offset-top | 锚点自动吸顶时与顶部的距离 | _number_ | `0` |
| highlight-color | 索引字符高亮颜色 | _string_ | `#ee0a24` | | highlight-color | 索引字符高亮颜色 | _string_ | `#ee0a24` |
| teleport `v3.0.19` | 指定索引栏挂载的节点 | _string \| Element_ | - |
### IndexAnchor Props ### IndexAnchor Props

View File

@ -193,3 +193,16 @@ test('should scroll to target element after calling scrollTo method', () => {
expect(scrollIntoView).toHaveBeenCalledTimes(1); expect(scrollIntoView).toHaveBeenCalledTimes(1);
expect(onSelect).toHaveBeenCalledWith('C'); expect(onSelect).toHaveBeenCalledWith('C');
}); });
test('should render teleport prop correctly', () => {
const root = document.createElement('div');
mount({
render: () => (
<IndexBar teleport={root}>
<IndexAnchor index="A">Title A</IndexAnchor>
</IndexBar>
),
});
expect(root.querySelector('.van-index-bar__sidebar')).toBeTruthy();
});