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>
<a-list
class="demo-loadmore-list"
:loading="loading"
:loading="initLoading"
item-layout="horizontal"
:data-source="dataList"
:data-source="list"
>
<template #loadMore>
<div :style="{ textAlign: 'center', marginTop: '12px', height: '32px', lineHeight: '32px' }">
<a-spin v-if="loadingMore" />
<a-button v-else @click="loadMore">loading more</a-button>
<div
v-if="!initLoading && !loading"
:style="{ textAlign: 'center', marginTop: '12px', height: '32px', lineHeight: '32px' }"
>
<a-button @click="onLoadMore">loading more</a-button>
</div>
</template>
<template #renderItem="{ item }">
<a-list-item>
<template #actions>
<a>edit</a>
<a>more</a>
<a key="list-loadmore-edit">edit</a>
<a key="list-loadmore-more">more</a>
</template>
<a-skeleton avatar :title="false" :loading="!!item.loading" active>
<a-list-item-meta
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>
</template>
<template #avatar>
<a-avatar src="https://joeschmoe.io/api/v1/random" />
<a-avatar :src="item.picture.large" />
</template>
</a-list-item-meta>
<div>content</div>
</a-skeleton>
</a-list-item>
</template>
</a-list>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { useLoadMore } from 'vue-request';
const getFakeData = () => `https://randomuser.me/api/?results=5&inc=name,gender,email,nat&noinfo`;
import { defineComponent, onMounted, ref, nextTick } from 'vue';
const count = 3;
const fakeDataUrl = `https://randomuser.me/api/?results=${count}&inc=name,gender,email,nat,picture&noinfo`;
export default defineComponent({
setup() {
const { dataList, loading, loadingMore, loadMore } = useLoadMore(getFakeData, {
listKey: 'results',
const initLoading = ref(true);
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 {
loading,
loadingMore,
dataList,
loadMore,
initLoading,
data,
list,
onLoadMore,
};
},
});

View File

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

View File

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

View File

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