diff --git a/src/_common b/src/_common index fe449a2ad..a827f05ce 160000 --- a/src/_common +++ b/src/_common @@ -1 +1 @@ -Subproject commit fe449a2ad4a247e0abb49e995f459c19644d8bbf +Subproject commit a827f05ced50e7191612283b12930053c126b0a1 diff --git a/src/list/__tests__/__snapshots__/index.test.jsx.snap b/src/list/__tests__/__snapshots__/index.test.jsx.snap index e3b5d6d9b..467a2038a 100644 --- a/src/list/__tests__/__snapshots__/index.test.jsx.snap +++ b/src/list/__tests__/__snapshots__/index.test.jsx.snap @@ -27,36 +27,36 @@ exports[`List > :props > :asyncLoading is a string 1`] = ` text
-
- - -
- - +
- 正在加载中,请稍后 + + +
+ +
+ + 正在加载中,请稍等 + @@ -72,9 +72,11 @@ exports[`List > :props > :asyncLoading is load-more 1`] = ` text
- + + 点击加载更多 +
`; diff --git a/src/list/_example-composition/virtual-scroll.vue b/src/list/_example-composition/virtual-scroll.vue new file mode 100644 index 000000000..f1352bcda --- /dev/null +++ b/src/list/_example-composition/virtual-scroll.vue @@ -0,0 +1,13 @@ + + diff --git a/src/list/_example/virtual-scroll.vue b/src/list/_example/virtual-scroll.vue new file mode 100644 index 000000000..386f9994b --- /dev/null +++ b/src/list/_example/virtual-scroll.vue @@ -0,0 +1,22 @@ + + diff --git a/src/list/hooks/useListItem.ts b/src/list/hooks/useListItem.ts new file mode 100644 index 000000000..4d4b1fb4c --- /dev/null +++ b/src/list/hooks/useListItem.ts @@ -0,0 +1,28 @@ +import { VNode } from 'vue'; +import { computed, getCurrentInstance } from '@vue/composition-api'; + +const useListItems = () => { + const instance = getCurrentInstance(); + const currentSlots = instance.proxy.$slots.default || []; + + const listItems = computed(() => { + const computedListItems: VNode[] = []; + currentSlots.forEach((child) => { + if (child.componentOptions?.tag === 't-list-item') { + computedListItems.push({ + class: child.data.staticClass, + style: child.data.staticStyle, + ...child.componentOptions.propsData, + slots: () => child.componentOptions.children, + } as unknown as VNode); + } + }); + return computedListItems; + }); + + return { + listItems, + }; +}; + +export default useListItems; diff --git a/src/list/hooks/useListVirtualScroll.ts b/src/list/hooks/useListVirtualScroll.ts new file mode 100644 index 000000000..d34449516 --- /dev/null +++ b/src/list/hooks/useListVirtualScroll.ts @@ -0,0 +1,57 @@ +import { Ref, computed } from '@vue/composition-api'; +import useVirtualScroll from '../../hooks/useVirtualScrollNew'; +import { TdListProps } from '../type'; +import { Styles } from '../../common'; + +const useListVirtualScroll = (scroll: TdListProps['scroll'], listRef: Ref, listItems: Ref) => { + const virtualScrollParams = computed(() => ({ + data: listItems.value, + scroll, + })); + const virtualConfig = useVirtualScroll(listRef, virtualScrollParams); + const isVirtualScroll = computed(() => virtualConfig.isVirtualScroll.value); + let lastScrollY = -1; + + const onInnerVirtualScroll = (e: WheelEvent) => { + const target = (e.target || e.srcElement) as HTMLElement; + const top = target.scrollTop; + if (lastScrollY !== top) { + virtualConfig.isVirtualScroll.value && virtualConfig.handleScroll(); + } else { + lastScrollY = -1; + } + lastScrollY = top; + }; + + const cursorStyle = computed( + () => ({ + position: 'absolute', + width: '1px', + height: '1px', + transition: 'transform 0.2s', + transform: `translate(0, ${virtualConfig.scrollHeight.value}px)`, + '-ms-transform': `translate(0, ${virtualConfig.scrollHeight.value}px)`, + '-moz-transform': `translate(0, ${virtualConfig.scrollHeight.value}px)`, + '-webkit-transform': `translate(0, ${virtualConfig.scrollHeight.value}px)`, + } as Styles), + ); + + const listStyle = computed( + () => ({ + transform: `translate(0, ${virtualConfig.translateY.value}px)`, + '-ms-transform': `translate(0, ${virtualConfig.translateY.value}px)`, + '-moz-transform': `translate(0, ${virtualConfig.translateY.value}px)`, + '-webkit-transform': `translate(0, ${virtualConfig.translateY.value}px)`, + } as Styles), + ); + + return { + virtualConfig, + cursorStyle, + listStyle, + isVirtualScroll, + onInnerVirtualScroll, + }; +}; + +export default useListVirtualScroll; diff --git a/src/list/list-item-meta-props.ts b/src/list/list-item-meta-props.ts index 990419405..c0e79937b 100644 --- a/src/list/list-item-meta-props.ts +++ b/src/list/list-item-meta-props.ts @@ -2,7 +2,6 @@ /** * 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC - * updated at 2021-11-19 10:44:26 * */ import { TdListItemMetaProps } from '../list/type'; diff --git a/src/list/list-item-props.ts b/src/list/list-item-props.ts index efb1ad6b8..99cfcd035 100644 --- a/src/list/list-item-props.ts +++ b/src/list/list-item-props.ts @@ -2,7 +2,6 @@ /** * 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC - * updated at 2021-11-19 10:44:26 * */ import { TdListItemProps } from '../list/type'; diff --git a/src/list/list-item.tsx b/src/list/list-item.tsx index 51f080683..7798f98a3 100644 --- a/src/list/list-item.tsx +++ b/src/list/list-item.tsx @@ -1,29 +1,33 @@ -import { VNode } from 'vue'; +import { defineComponent } from '@vue/composition-api'; import props from './list-item-props'; +import { usePrefixClass } from '../hooks/useConfig'; import { renderTNodeJSX, renderContent } from '../utils/render-tnode'; -import { getClassPrefixMixins } from '../config-provider/config-receiver'; -import mixins from '../utils/mixins'; -const classPrefixMixins = getClassPrefixMixins('list-item'); - -export default mixins(classPrefixMixins).extend({ +export default defineComponent({ name: 'TListItem', props, - methods: { - handleClick(e: MouseEvent): void { - this.$emit('click', { e }); - this.onClick?.({ e }); - }, + setup(props, { emit }) { + const componentName = usePrefixClass('list-item'); + + const handleClick = (e: MouseEvent) => { + emit('click', { e }); + props.onClick?.({ e }); + }; + return { + componentName, + handleClick, + }; }, - render(): VNode { + render() { + const { componentName, handleClick } = this; const content = renderContent(this, 'default', 'content'); const propsActionContent = renderTNodeJSX(this, 'action'); return ( -
  • -
    -
    {content}
    - {propsActionContent &&
  • {propsActionContent}
  • } +
  • +
    +
    {content}
    + {propsActionContent &&
  • {propsActionContent}
  • } ); diff --git a/src/list/list.en-US.md b/src/list/list.en-US.md index 019660404..49e003de7 100644 --- a/src/list/list.en-US.md +++ b/src/list/list.en-US.md @@ -1,6 +1,7 @@ :: BASE_DOC :: ## API + ### List Props name | type | default | description | required @@ -8,8 +9,9 @@ name | type | default | description | required asyncLoading | String / Slot / Function | - | Typescript:`string \| TNode`。[see more ts definition](https://github.com/Tencent/tdesign-vue/blob/develop/src/common.ts) | N footer | String / Slot / Function | - | Typescript:`string \| TNode`。[see more ts definition](https://github.com/Tencent/tdesign-vue/blob/develop/src/common.ts) | N header | String / Slot / Function | - | Typescript:`string \| TNode`。[see more ts definition](https://github.com/Tencent/tdesign-vue/blob/develop/src/common.ts) | N -layout | String | horizontal | options:horizontal/vertical | N -size | String | medium | options:small/medium/large | N +layout | String | horizontal | options: horizontal/vertical | N +scroll | Object | - | lazy load and virtual scroll。Typescript:`TScroll`。[see more ts definition](https://github.com/Tencent/tdesign-vue/blob/develop/src/common.ts) | N +size | String | medium | options: small/medium/large | N split | Boolean | false | \- | N stripe | Boolean | false | \- | N onLoadMore | Function | | Typescript:`(options: { e: MouseEvent }) => void`
    | N @@ -22,6 +24,7 @@ name | params | description load-more | `(options: { e: MouseEvent })` | \- scroll | `(options: { e: Event \| WheelEvent; scrollTop: number; scrollBottom: number })` | \- + ### ListItem Props name | type | default | description | required @@ -29,13 +32,7 @@ name | type | default | description | required action | String / Slot / Function | - | Typescript:`string \| TNode`。[see more ts definition](https://github.com/Tencent/tdesign-vue/blob/develop/src/common.ts) | N content | String / Slot / Function | - | Typescript:`string \| TNode`。[see more ts definition](https://github.com/Tencent/tdesign-vue/blob/develop/src/common.ts) | N default | String / Slot / Function | - | Typescript:`string \| TNode`。[see more ts definition](https://github.com/Tencent/tdesign-vue/blob/develop/src/common.ts) | N -onClick | Function | | Typescript:`(context: { e: MouseEvent }) => void`
    | N - -### ListItem Events -name | params | description --- | -- | -- -click | `(context: { e: MouseEvent })` | \- ### ListItemMeta Props diff --git a/src/list/list.md b/src/list/list.md index c3614f8fa..13782b1c9 100644 --- a/src/list/list.md +++ b/src/list/list.md @@ -1,38 +1,16 @@ :: BASE_DOC :: -### 斑马纹的列表 - -当列表内容较多时,可以使用斑马纹样式,便于用户获取信息。 - -{{ stripe }} - -### 异步加载的列表 - -当数据需要通过二次请求加载展示时,可以通过`asyncLoading`来处理相关的逻辑。 - -{{ loading }} - -### 带头部及尾部的列表 - -当列表需要展示头部或尾部信息时,可以通过`header`或`footer`来配置。 - -{{ header-footer }} - -### 带滚动事件的列表 - -当列表较长时,可以配置滚动条及事件来进行滚动处理 - -{{ scroll }} - ## API + ### List Props -名称 | 类型 | 默认值 | 说明 | 必传 +名称 | 类型 | 默认值 | 描述 | 必传 -- | -- | -- | -- | -- asyncLoading | String / Slot / Function | - | 自定义加载中。值为空不显示加载中,值为 'loading' 显示加载中状态,值为 'load-more' 显示加载更多状态。值类型为函数,则表示自定义加载状态呈现内容。TS 类型:`string \| TNode`。[通用类型定义](https://github.com/Tencent/tdesign-vue/blob/develop/src/common.ts) | N footer | String / Slot / Function | - | 底部。TS 类型:`string \| TNode`。[通用类型定义](https://github.com/Tencent/tdesign-vue/blob/develop/src/common.ts) | N header | String / Slot / Function | - | 头部。TS 类型:`string \| TNode`。[通用类型定义](https://github.com/Tencent/tdesign-vue/blob/develop/src/common.ts) | N layout | String | horizontal | 排列方式(待设计稿输出)。可选项:horizontal/vertical | N +scroll | Object | - | 懒加载和虚拟滚动。为保证组件收益最大化,当数据量小于阈值 `scroll.threshold` 时,无论虚拟滚动的配置是否存在,组件内部都不会开启虚拟滚动,`scroll.threshold` 默认为 `100`。TS 类型:`TScroll`。[通用类型定义](https://github.com/Tencent/tdesign-vue/blob/develop/src/common.ts) | N size | String | medium | 尺寸。可选项:small/medium/large | N split | Boolean | false | 是否展示分割线 | N stripe | Boolean | false | 是否展示斑马纹 | N @@ -46,25 +24,19 @@ onScroll | Function | | TS 类型:`(options: { e: Event \| WheelEvent; scroll load-more | `(options: { e: MouseEvent })` | 点击加载更多时触发 scroll | `(options: { e: Event \| WheelEvent; scrollTop: number; scrollBottom: number })` | 列表滚动时触发,scrollTop 表示顶部滚动距离,scrollBottom 表示底部滚动距离 + ### ListItem Props -名称 | 类型 | 默认值 | 说明 | 必传 +名称 | 类型 | 默认值 | 描述 | 必传 -- | -- | -- | -- | -- action | String / Slot / Function | - | 操作栏。TS 类型:`string \| TNode`。[通用类型定义](https://github.com/Tencent/tdesign-vue/blob/develop/src/common.ts) | N content | String / Slot / Function | - | 内容。TS 类型:`string \| TNode`。[通用类型定义](https://github.com/Tencent/tdesign-vue/blob/develop/src/common.ts) | N default | String / Slot / Function | - | 内容,同 content。TS 类型:`string \| TNode`。[通用类型定义](https://github.com/Tencent/tdesign-vue/blob/develop/src/common.ts) | N -onClick | Function | | TS 类型:`(context: { e: MouseEvent }) => void`
    点击时触发 | N - -### ListItem Events - -名称 | 参数 | 描述 --- | -- | -- -click | `(context: { e: MouseEvent })` | 点击时触发 ### ListItemMeta Props -名称 | 类型 | 默认值 | 说明 | 必传 +名称 | 类型 | 默认值 | 描述 | 必传 -- | -- | -- | -- | -- avatar | String / Slot / Function | - | 已废弃。列表项图片。TS 类型:`string \| TNode`。[通用类型定义](https://github.com/Tencent/tdesign-vue/blob/develop/src/common.ts) | N description | String / Slot / Function | - | 列表项内容。TS 类型:`string \| TNode`。[通用类型定义](https://github.com/Tencent/tdesign-vue/blob/develop/src/common.ts) | N diff --git a/src/list/list.tsx b/src/list/list.tsx index 1ec2af613..d54ab27ff 100644 --- a/src/list/list.tsx +++ b/src/list/list.tsx @@ -1,102 +1,130 @@ -import { VNode } from 'vue'; -import { ScopedSlotReturnValue } from 'vue/types/vnode'; -import Loading from '../loading'; +import { defineComponent, computed, ref } from '@vue/composition-api'; +import isString from 'lodash/isString'; +import omit from 'lodash/omit'; +import TLoading from '../loading'; +import TListItem from './list-item'; import props from './props'; -import { renderTNodeJSX } from '../utils/render-tnode'; import { LOAD_MORE, LOADING } from './const'; -import { ClassName } from '../common'; -import { getClassPrefixMixins } from '../config-provider/config-receiver'; -import mixins from '../utils/mixins'; - -const classPrefixMixins = getClassPrefixMixins('list'); +import { useConfig, usePrefixClass, useCommonClassName } from '../hooks/useConfig'; +import useListVirtualScroll from './hooks/useListVirtualScroll'; +import { renderTNodeJSX } from '../utils/render-tnode'; +import useListItems from './hooks/useListItem'; +import type { TdListProps } from './type'; -export default mixins(classPrefixMixins).extend({ +export default defineComponent({ name: 'TList', - props: { - ...props, - }, - computed: { - listClass(): ClassName { - return [ - `${this.componentName}`, - this.commonSizeClassName[this.size], - { - [`${this.componentName}--split`]: this.split, - [`${this.componentName}--stripe`]: this.stripe, - [`${this.componentName}--vertical-action`]: this.layout === 'vertical', - }, - ]; - }, - loadingClass(): ClassName { - if (this.asyncLoading === 'loading') return this.commonStatusClassName.loading; - if (this.asyncLoading === 'load-more') return this.commonStatusClassName.loadMore; - return ''; - }, - }, - components: { - Loading, - }, - methods: { - renderLoading() { - if (this.asyncLoading && typeof this.asyncLoading === 'string') { - const text = { - [LOADING]: '正在加载中,请稍后', - [LOAD_MORE]: '点击加载更多', - }[this.asyncLoading]; - const loading = this.asyncLoading === LOADING; - return ; - } - return renderTNodeJSX(this, 'asyncLoading'); - }, - handleScroll(e: WheelEvent | Event) { - const listElement = this.$el as HTMLElement; + props, + setup(props: TdListProps, { emit }) { + const listRef = ref(); + + const { globalConfig } = useConfig('list'); + const componentName = usePrefixClass('list'); + const { SIZE } = useCommonClassName(); + const { listItems } = useListItems(); + const listClass = computed(() => [ + `${componentName.value}`, + SIZE.value[props.size], + { + [`${componentName.value}--split`]: props.split, + [`${componentName.value}--stripe`]: props.stripe, + [`${componentName.value}--vertical-action`]: props.layout === 'vertical', + }, + ]); + + const loadingClass = computed(() => isString(props.asyncLoading) && ['loading', 'load-more'].includes(props.asyncLoading) + ? `${componentName.value}__load ${componentName.value}__load--${props.asyncLoading}` + : `${componentName.value}__load`); + + const { + virtualConfig, cursorStyle, listStyle, isVirtualScroll, onInnerVirtualScroll, + } = useListVirtualScroll( + props.scroll, + listRef, + listItems, + ); + const handleScroll = (e: WheelEvent) => { + const listElement = e.target as HTMLElement; const { scrollTop, scrollHeight, clientHeight } = listElement; - this.$emit('scroll', { - $event: e, + if (isVirtualScroll.value) onInnerVirtualScroll(e); + const scrollParams = { + e, scrollTop, scrollBottom: scrollHeight - clientHeight - scrollTop, - }); - if (this.onScroll) { - this.onScroll({ - e, - scrollTop, - scrollBottom: scrollHeight - clientHeight - scrollTop, - }); - } - }, - handleLoadMore(e: MouseEvent) { - if (typeof this.asyncLoading === 'string' && this.asyncLoading !== LOAD_MORE) return; - this.$emit('load-more', { e }); - if (this.onLoadMore) { - this.onLoadMore({ - e, - }); - } - }, - renderContent() { - const propsHeaderContent = renderTNodeJSX(this, 'header'); - const propsFooterContent = renderTNodeJSX(this, 'footer'); + }; + emit('scroll', scrollParams); + + props.onScroll?.(scrollParams); + }; - return [ - propsHeaderContent &&
    {propsHeaderContent}
    , -
      {renderTNodeJSX(this, 'default')}
    , - propsFooterContent &&
    {propsFooterContent}
    , - ]; - }, + const handleLoadMore = (e: MouseEvent) => { + if (isString(props.asyncLoading) && props.asyncLoading !== LOAD_MORE) return; + emit('load-more', { e }); + props.onLoadMore?.({ e }); + }; + + return { + componentName, + listClass, + loadingClass, + handleScroll, + handleLoadMore, + listRef, + globalConfig, + virtualConfig, + cursorStyle, + listStyle, + isVirtualScroll, + }; }, - render(): VNode { - let listContent: ScopedSlotReturnValue = this.renderContent(); - listContent = [ - listContent, -
    - {this.renderLoading()} -
    , - ]; + render() { + const { + isVirtualScroll, cursorStyle, listStyle, componentName, globalConfig, virtualConfig, + } = this; + + const propsHeaderContent = renderTNodeJSX(this, 'header'); + const propsFooterContent = renderTNodeJSX(this, 'footer'); + const renderLoading = () => { + if (this.asyncLoading && isString(this.asyncLoading)) { + if (this.asyncLoading === LOADING) { + return ( +
    + + {globalConfig.loadingText} +
    + ); + } + if (this.asyncLoading === LOAD_MORE) { + return {globalConfig.loadingMoreText}; + } + } + return renderTNodeJSX(this, 'asyncLoading'); + }; return ( -
    - {listContent} +
    + {propsHeaderContent ?
    {propsHeaderContent}
    : null} + {isVirtualScroll ? ( +
    +
    +
      + {virtualConfig.visibleData.value.map((item) => ( + + ))} +
    +
    + ) : ( +
      {renderTNodeJSX(this, 'default')}
    + )} + {propsFooterContent ?
    {propsFooterContent}
    : null} +
    + {renderLoading()} +
    ); }, diff --git a/src/list/props.ts b/src/list/props.ts index e931c5d15..51e570ce9 100644 --- a/src/list/props.ts +++ b/src/list/props.ts @@ -2,7 +2,6 @@ /** * 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC - * updated at 2021-11-19 10:44:26 * */ import { TdListProps } from './type'; @@ -26,14 +25,20 @@ export default { type: String as PropType, default: 'horizontal' as TdListProps['layout'], validator(val: TdListProps['layout']): boolean { + if (!val) return true; return ['horizontal', 'vertical'].includes(val); }, }, + /** 懒加载和虚拟滚动。为保证组件收益最大化,当数据量小于阈值 `scroll.threshold` 时,无论虚拟滚动的配置是否存在,组件内部都不会开启虚拟滚动,`scroll.threshold` 默认为 `100` */ + scroll: { + type: Object as PropType, + }, /** 尺寸 */ size: { type: String as PropType, default: 'medium' as TdListProps['size'], validator(val: TdListProps['size']): boolean { + if (!val) return true; return ['small', 'medium', 'large'].includes(val); }, }, diff --git a/src/list/type.ts b/src/list/type.ts index 35d685e84..74b4e47b2 100644 --- a/src/list/type.ts +++ b/src/list/type.ts @@ -2,10 +2,9 @@ /** * 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC - * updated at 2021-11-19 10:44:26 * */ -import { TNode } from '../common'; +import { TNode, TScroll } from '../common'; export interface TdListProps { /** @@ -25,6 +24,10 @@ export interface TdListProps { * @default horizontal */ layout?: 'horizontal' | 'vertical'; + /** + * 懒加载和虚拟滚动。为保证组件收益最大化,当数据量小于阈值 `scroll.threshold` 时,无论虚拟滚动的配置是否存在,组件内部都不会开启虚拟滚动,`scroll.threshold` 默认为 `100` + */ + scroll?: TScroll; /** * 尺寸 * @default medium @@ -65,6 +68,7 @@ export interface TdListItemProps { default?: string | TNode; /** * 点击时触发 + * @deprecated */ onClick?: (context: { e: MouseEvent }) => void; } diff --git a/test/snap/__snapshots__/csr.test.js.snap b/test/snap/__snapshots__/csr.test.js.snap index a1f953588..c1b1cfbb8 100644 --- a/test/snap/__snapshots__/csr.test.js.snap +++ b/test/snap/__snapshots__/csr.test.js.snap @@ -68023,9 +68023,11 @@ exports[`csr snapshot test > csr test ./src/list/_example/loading.vue 1`] = `
    - + + 点击加载更多 +
    @@ -68927,6 +68929,1137 @@ exports[`csr snapshot test > csr test ./src/list/_example/stripe.vue 1`] = ` `; +exports[`csr snapshot test > csr test ./src/list/_example/virtual-scroll.vue 1`] = ` +
    +
    +
    +
      +
    • +
      +
      +
      +
      + +
      +
      +

      + 列表标题 +

      +

      + 第1个列表内容的描述性文字 +

      +
      +
      +
      +
      +
    • +
    • +
      +
      +
      +
      + +
      +
      +

      + 列表标题 +

      +

      + 第2个列表内容的描述性文字 +

      +
      +
      +
      +
      +
    • +
    • +
      +
      +
      +
      + +
      +
      +

      + 列表标题 +

      +

      + 第3个列表内容的描述性文字 +

      +
      +
      +
      +
      +
    • +
    • +
      +
      +
      +
      + +
      +
      +

      + 列表标题 +

      +

      + 第4个列表内容的描述性文字 +

      +
      +
      +
      +
      +
    • +
    • +
      +
      +
      +
      + +
      +
      +

      + 列表标题 +

      +

      + 第5个列表内容的描述性文字 +

      +
      +
      +
      +
      +
    • +
    • +
      +
      +
      +
      + +
      +
      +

      + 列表标题 +

      +

      + 第6个列表内容的描述性文字 +

      +
      +
      +
      +
      +
    • +
    • +
      +
      +
      +
      + +
      +
      +

      + 列表标题 +

      +

      + 第7个列表内容的描述性文字 +

      +
      +
      +
      +
      +
    • +
    • +
      +
      +
      +
      + +
      +
      +

      + 列表标题 +

      +

      + 第8个列表内容的描述性文字 +

      +
      +
      +
      +
      +
    • +
    • +
      +
      +
      +
      + +
      +
      +

      + 列表标题 +

      +

      + 第9个列表内容的描述性文字 +

      +
      +
      +
      +
      +
    • +
    • +
      +
      +
      +
      + +
      +
      +

      + 列表标题 +

      +

      + 第10个列表内容的描述性文字 +

      +
      +
      +
      +
      +
    • +
    • +
      +
      +
      +
      + +
      +
      +

      + 列表标题 +

      +

      + 第11个列表内容的描述性文字 +

      +
      +
      +
      +
      +
    • +
    • +
      +
      +
      +
      + +
      +
      +

      + 列表标题 +

      +

      + 第12个列表内容的描述性文字 +

      +
      +
      +
      +
      +
    • +
    • +
      +
      +
      +
      + +
      +
      +

      + 列表标题 +

      +

      + 第13个列表内容的描述性文字 +

      +
      +
      +
      +
      +
    • +
    • +
      +
      +
      +
      + +
      +
      +

      + 列表标题 +

      +

      + 第14个列表内容的描述性文字 +

      +
      +
      +
      +
      +
    • +
    • +
      +
      +
      +
      + +
      +
      +

      + 列表标题 +

      +

      + 第15个列表内容的描述性文字 +

      +
      +
      +
      +
      +
    • +
    • +
      +
      +
      +
      + +
      +
      +

      + 列表标题 +

      +

      + 第16个列表内容的描述性文字 +

      +
      +
      +
      +
      +
    • +
    • +
      +
      +
      +
      + +
      +
      +

      + 列表标题 +

      +

      + 第17个列表内容的描述性文字 +

      +
      +
      +
      +
      +
    • +
    • +
      +
      +
      +
      + +
      +
      +

      + 列表标题 +

      +

      + 第18个列表内容的描述性文字 +

      +
      +
      +
      +
      +
    • +
    • +
      +
      +
      +
      + +
      +
      +

      + 列表标题 +

      +

      + 第19个列表内容的描述性文字 +

      +
      +
      +
      +
      +
    • +
    • +
      +
      +
      +
      + +
      +
      +

      + 列表标题 +

      +

      + 第20个列表内容的描述性文字 +

      +
      +
      +
      +
      +
    • +
    • +
      +
      +
      +
      + +
      +
      +

      + 列表标题 +

      +

      + 第21个列表内容的描述性文字 +

      +
      +
      +
      +
      +
    • +
    • +
      +
      +
      +
      + +
      +
      +

      + 列表标题 +

      +

      + 第22个列表内容的描述性文字 +

      +
      +
      +
      +
      +
    • +
    • +
      +
      +
      +
      + +
      +
      +

      + 列表标题 +

      +

      + 第23个列表内容的描述性文字 +

      +
      +
      +
      +
      +
    • +
    • +
      +
      +
      +
      + +
      +
      +

      + 列表标题 +

      +

      + 第24个列表内容的描述性文字 +

      +
      +
      +
      +
      +
    • +
    • +
      +
      +
      +
      + +
      +
      +

      + 列表标题 +

      +

      + 第25个列表内容的描述性文字 +

      +
      +
      +
      +
      +
    • +
    • +
      +
      +
      +
      + +
      +
      +

      + 列表标题 +

      +

      + 第26个列表内容的描述性文字 +

      +
      +
      +
      +
      +
    • +
    • +
      +
      +
      +
      + +
      +
      +

      + 列表标题 +

      +

      + 第27个列表内容的描述性文字 +

      +
      +
      +
      +
      +
    • +
    • +
      +
      +
      +
      + +
      +
      +

      + 列表标题 +

      +

      + 第28个列表内容的描述性文字 +

      +
      +
      +
      +
      +
    • +
    • +
      +
      +
      +
      + +
      +
      +

      + 列表标题 +

      +

      + 第29个列表内容的描述性文字 +

      +
      +
      +
      +
      +
    • +
    • +
      +
      +
      +
      + +
      +
      +

      + 列表标题 +

      +

      + 第30个列表内容的描述性文字 +

      +
      +
      +
      +
      +
    • +
    +
    +
    +
    +`; + exports[`csr snapshot test > csr test ./src/loading/_example/attach.vue 1`] = `
    renders ./src/list/_example/header-footer.vue corre exports[`ssr snapshot test > renders ./src/list/_example/image-text.vue correctly 1`] = `"
    • 列表标题

      列表内容的描述性文字

    • 列表标题

      列表内容的描述性文字

    • 列表标题

      列表内容的描述性文字

    • 列表标题

      列表内容的描述性文字

    "`; -exports[`ssr snapshot test > renders ./src/list/_example/loading.vue correctly 1`] = `"
    • 列表标题

      列表内容的描述性文字

    • 列表标题

      列表内容的描述性文字

    • 列表标题

      列表内容的描述性文字

    "`; +exports[`ssr snapshot test > renders ./src/list/_example/loading.vue correctly 1`] = `"
    • 列表标题

      列表内容的描述性文字

    • 列表标题

      列表内容的描述性文字

    • 列表标题

      列表内容的描述性文字

    点击加载更多
    "`; exports[`ssr snapshot test > renders ./src/list/_example/multiline.vue correctly 1`] = `"
    • 列表标题

      列表内容的描述性文字

    • 列表标题

      列表内容的描述性文字

    • 列表标题

      列表内容的描述性文字

    "`; @@ -626,6 +626,8 @@ exports[`ssr snapshot test > renders ./src/list/_example/size.vue correctly 1`] exports[`ssr snapshot test > renders ./src/list/_example/stripe.vue correctly 1`] = `"
    • 列表内容的描述性文字
    • 列表内容的描述性文字
    • 列表内容的描述性文字
    • 列表内容的描述性文字
    "`; +exports[`ssr snapshot test > renders ./src/list/_example/virtual-scroll.vue correctly 1`] = `"
    • 列表标题

      第1个列表内容的描述性文字

    • 列表标题

      第2个列表内容的描述性文字

    • 列表标题

      第3个列表内容的描述性文字

    • 列表标题

      第4个列表内容的描述性文字

    • 列表标题

      第5个列表内容的描述性文字

    • 列表标题

      第6个列表内容的描述性文字

    • 列表标题

      第7个列表内容的描述性文字

    • 列表标题

      第8个列表内容的描述性文字

    • 列表标题

      第9个列表内容的描述性文字

    • 列表标题

      第10个列表内容的描述性文字

    • 列表标题

      第11个列表内容的描述性文字

    • 列表标题

      第12个列表内容的描述性文字

    • 列表标题

      第13个列表内容的描述性文字

    • 列表标题

      第14个列表内容的描述性文字

    • 列表标题

      第15个列表内容的描述性文字

    • 列表标题

      第16个列表内容的描述性文字

    • 列表标题

      第17个列表内容的描述性文字

    • 列表标题

      第18个列表内容的描述性文字

    • 列表标题

      第19个列表内容的描述性文字

    • 列表标题

      第20个列表内容的描述性文字

    • 列表标题

      第21个列表内容的描述性文字

    • 列表标题

      第22个列表内容的描述性文字

    • 列表标题

      第23个列表内容的描述性文字

    • 列表标题

      第24个列表内容的描述性文字

    • 列表标题

      第25个列表内容的描述性文字

    • 列表标题

      第26个列表内容的描述性文字

    • 列表标题

      第27个列表内容的描述性文字

    • 列表标题

      第28个列表内容的描述性文字

    • 列表标题

      第29个列表内容的描述性文字

    • 列表标题

      第30个列表内容的描述性文字

    "`; + exports[`ssr snapshot test > renders ./src/loading/_example/attach.vue correctly 1`] = `"
    Hello, I'm Alice. I'm going to be a front-end developer.
    显示
    "`; exports[`ssr snapshot test > renders ./src/loading/_example/base.vue correctly 1`] = `"
    "`;