style: update list

feat-css-var
tangjinzhou 2022-03-01 16:31:16 +08:00
parent 4320dd6434
commit f882d3e87c
6 changed files with 91 additions and 39 deletions

View File

@ -19,22 +19,25 @@ Load more list with `loadMore` property.
<template> <template>
<a-list <a-list
class="demo-loadmore-list" class="demo-loadmore-list"
:loading="loading" :loading="initLoading"
item-layout="horizontal" item-layout="horizontal"
:data-source="dataList" :data-source="list"
> >
<template #loadMore> <template #loadMore>
<div :style="{ textAlign: 'center', marginTop: '12px', height: '32px', lineHeight: '32px' }"> <div
<a-spin v-if="loadingMore" /> v-if="!initLoading && !loading"
<a-button v-else @click="loadMore">loading more</a-button> :style="{ textAlign: 'center', marginTop: '12px', height: '32px', lineHeight: '32px' }"
>
<a-button @click="onLoadMore">loading more</a-button>
</div> </div>
</template> </template>
<template #renderItem="{ item }"> <template #renderItem="{ item }">
<a-list-item> <a-list-item>
<template #actions> <template #actions>
<a>edit</a> <a key="list-loadmore-edit">edit</a>
<a>more</a> <a key="list-loadmore-more">more</a>
</template> </template>
<a-skeleton avatar :title="false" :loading="!!item.loading" active>
<a-list-item-meta <a-list-item-meta
description="Ant Design, a design language for background applications, is refined by Ant UED Team" description="Ant Design, a design language for background applications, is refined by Ant UED Team"
> >
@ -42,31 +45,63 @@ Load more list with `loadMore` property.
<a href="https://www.antdv.com/">{{ item.name.last }}</a> <a href="https://www.antdv.com/">{{ item.name.last }}</a>
</template> </template>
<template #avatar> <template #avatar>
<a-avatar src="https://joeschmoe.io/api/v1/random" /> <a-avatar :src="item.picture.large" />
</template> </template>
</a-list-item-meta> </a-list-item-meta>
<div>content</div> <div>content</div>
</a-skeleton>
</a-list-item> </a-list-item>
</template> </template>
</a-list> </a-list>
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent, onMounted, ref, nextTick } from 'vue';
import { useLoadMore } from 'vue-request'; const count = 3;
const fakeDataUrl = `https://randomuser.me/api/?results=${count}&inc=name,gender,email,nat,picture&noinfo`;
const getFakeData = () => `https://randomuser.me/api/?results=5&inc=name,gender,email,nat&noinfo`;
export default defineComponent({ export default defineComponent({
setup() { setup() {
const { dataList, loading, loadingMore, loadMore } = useLoadMore(getFakeData, { const initLoading = ref(true);
listKey: 'results', const loading = ref(false);
const data = ref([]);
const list = ref([]);
onMounted(() => {
fetch(fakeDataUrl)
.then(res => res.json())
.then(res => {
initLoading.value = false;
data.value = res.results;
list.value = res.results;
}); });
});
const onLoadMore = () => {
loading.value = true;
list.value = data.value.concat(
[...new Array(count)].map(() => ({ loading: true, name: {}, picture: {} })),
);
fetch(fakeDataUrl)
.then(res => res.json())
.then(res => {
const newData = data.value.concat(res.results);
loading.value = false;
data.value = newData;
list.value = newData;
nextTick(() => {
// Resetting window's offsetTop so as to display react-virtualized demo underfloor.
// In real scene, you can using public method of react-virtualized:
// https://stackoverflow.com/questions/46700726/how-to-use-public-method-updateposition-of-react-virtualized
window.dispatchEvent(new Event('resize'));
});
});
};
return { return {
loading, loading,
loadingMore, initLoading,
dataList, data,
loadMore, list,
onLoadMore,
}; };
}, },
}); });

View File

@ -10,6 +10,7 @@ import { Row } from '../grid';
import Item from './Item'; import Item from './Item';
import { flattenChildren } from '../_util/props-util'; import { flattenChildren } from '../_util/props-util';
import initDefaultProps from '../_util/props-util/initDefaultProps'; import initDefaultProps from '../_util/props-util/initDefaultProps';
import type { Key } from '../_util/type';
import { tuple } from '../_util/type'; import { tuple } from '../_util/type';
import ItemMeta from './ItemMeta'; import ItemMeta from './ItemMeta';
import useConfigInject from '../_util/hooks/useConfigInject'; import useConfigInject from '../_util/hooks/useConfigInject';
@ -32,6 +33,7 @@ export interface ListGridType {
lg?: ColumnCount; lg?: ColumnCount;
xl?: ColumnCount; xl?: ColumnCount;
xxl?: ColumnCount; xxl?: ColumnCount;
xxxl?: ColumnCount;
} }
export const ListSize = tuple('small', 'default', 'large'); export const ListSize = tuple('small', 'default', 'large');
@ -53,7 +55,7 @@ export const listProps = {
]), ]),
), ),
prefixCls: PropTypes.string, prefixCls: PropTypes.string,
rowKey: PropTypes.any, rowKey: [String, Number, Function] as PropType<Key | ((item: any) => Key)>,
renderItem: PropTypes.any, renderItem: PropTypes.any,
size: PropTypes.oneOf(ListSize), size: PropTypes.oneOf(ListSize),
split: PropTypes.looseBool, split: PropTypes.looseBool,
@ -108,6 +110,8 @@ const List = defineComponent({
} }
}); });
const listItemsKeys: Key[] = [];
const triggerPaginationEvent = (eventName: string) => (page: number, pageSize: number) => { const triggerPaginationEvent = (eventName: string) => (page: number, pageSize: number) => {
paginationCurrent.value = page; paginationCurrent.value = page;
paginationSize.value = pageSize; paginationSize.value = pageSize;
@ -225,16 +229,16 @@ const List = defineComponent({
return undefined; return undefined;
}); });
const renderInnerItem = (keys: number[], item: any, index: number) => { const renderInnerItem = (item: any, index: number) => {
const renderItem = props.renderItem ?? slots.renderItem; const renderItem = props.renderItem ?? slots.renderItem;
if (!renderItem) return null; if (!renderItem) return null;
let key; let key;
const rowKeyType = typeof props.rowKey;
if (typeof props.rowKey === 'function') { if (rowKeyType === 'function') {
key = props.rowKey(item); key = (props.rowKey as any)(item);
} else if (typeof props.rowKey === 'string') { } else if (rowKeyType === 'string' || rowKeyType === 'number') {
key = item[props.rowKey]; key = item[props.rowKey as any];
} else { } else {
key = item.key; key = item.key;
} }
@ -243,7 +247,7 @@ const List = defineComponent({
key = `list-item-${index}`; key = `list-item-${index}`;
} }
keys[index] = key; listItemsKeys[index] = key;
return renderItem({ item, index }); return renderItem({ item, index });
}; };
@ -253,7 +257,6 @@ const List = defineComponent({
const footer = props.footer ?? slots.footer?.(); const footer = props.footer ?? slots.footer?.();
const header = props.header ?? slots.header?.(); const header = props.header ?? slots.header?.();
const children = flattenChildren(slots.default?.()); const children = flattenChildren(slots.default?.());
const keys = [];
const isSomethingAfterLastItem = !!(loadMore || props.pagination || footer); const isSomethingAfterLastItem = !!(loadMore || props.pagination || footer);
const classString = { const classString = {
...classObj.value, ...classObj.value,
@ -271,11 +274,12 @@ const List = defineComponent({
let childrenContent = isLoading.value && <div style={{ minHeight: '53px' }} />; let childrenContent = isLoading.value && <div style={{ minHeight: '53px' }} />;
if (splitDataSource.value.length > 0) { if (splitDataSource.value.length > 0) {
listItemsKeys.length = 0;
const items = splitDataSource.value.map((item: any, index: number) => const items = splitDataSource.value.map((item: any, index: number) =>
renderInnerItem(keys, item, index), renderInnerItem(item, index),
); );
const childrenList = items.map((child: any, index) => ( const childrenList = items.map((child: any, index) => (
<div key={keys[index]} style={colStyle.value}> <div key={listItemsKeys[index]} style={colStyle.value}>
{child} {child}
</div> </div>
)); ));

View File

@ -1,5 +1,6 @@
@import './index.less'; @import '../../style/themes/index';
@list-prefix-cls: ~'@{ant-prefix}-list';
@card-prefix-cls: ~'@{ant-prefix}-card'; @card-prefix-cls: ~'@{ant-prefix}-card';
.@{list-prefix-cls} { .@{list-prefix-cls} {

View File

@ -26,6 +26,7 @@
&-more { &-more {
margin-top: @margin-sm; margin-top: @margin-sm;
text-align: center; text-align: center;
button { button {
padding-right: 32px; padding-right: 32px;
padding-left: 32px; padding-left: 32px;
@ -66,30 +67,36 @@
&-avatar { &-avatar {
margin-right: @list-item-meta-avatar-margin-right; margin-right: @list-item-meta-avatar-margin-right;
} }
&-content { &-content {
flex: 1 0; flex: 1 0;
width: 0; width: 0;
color: @text-color; color: @text-color;
} }
&-title { &-title {
margin-bottom: 4px; margin-bottom: 4px;
color: @text-color; color: @text-color;
font-size: @font-size-base; font-size: @font-size-base;
line-height: @line-height-base; line-height: @line-height-base;
> a { > a {
color: @text-color; color: @text-color;
transition: all 0.3s; transition: all 0.3s;
&:hover { &:hover {
color: @primary-color; color: @primary-color;
} }
} }
} }
&-description { &-description {
color: @text-color-secondary; color: @text-color-secondary;
font-size: @list-item-meta-description-font-size; font-size: @list-item-meta-description-font-size;
line-height: @line-height-base; line-height: @line-height-base;
} }
} }
&-action { &-action {
flex: 0 0 auto; flex: 0 0 auto;
margin-left: 48px; margin-left: 48px;
@ -146,6 +153,7 @@
&-split &-item { &-split &-item {
border-bottom: 1px solid @border-color-split; border-bottom: 1px solid @border-color-split;
&:last-child { &:last-child {
border-bottom: none; border-bottom: none;
} }
@ -204,6 +212,7 @@
> li { > li {
padding: 0 @padding-md; padding: 0 @padding-md;
&:first-child { &:first-child {
padding-left: 0; padding-left: 0;
} }

View File

@ -20,6 +20,7 @@
.@{list-prefix-cls} { .@{list-prefix-cls} {
&-item { &-item {
flex-wrap: wrap; flex-wrap: wrap;
&-action { &-action {
margin-left: 12px; margin-left: 12px;
} }
@ -29,9 +30,11 @@
.@{list-prefix-cls}-vertical { .@{list-prefix-cls}-vertical {
.@{list-prefix-cls}-item { .@{list-prefix-cls}-item {
flex-wrap: wrap-reverse; flex-wrap: wrap-reverse;
&-main { &-main {
min-width: 220px; min-width: 220px;
} }
&-extra { &-extra {
margin: auto auto 16px; margin: auto auto 16px;
} }