feat: add CardList component

This commit is contained in:
JinMao 2021-08-27 05:51:58 +08:00
parent 1ddfc31c3c
commit 0f5ddbf1ec
7 changed files with 256 additions and 0 deletions

View File

@ -0,0 +1,4 @@
import { withInstall } from '/@/utils';
import cardList from './src/CardList.vue';
export const CardList = withInstall(cardList);

View File

@ -0,0 +1,185 @@
<template>
<div class="p-2">
<div class="bg-white mb-2 p-4">
<BasicForm @register="registerForm" />
</div>
{{ sliderProp.width }}
<div class="bg-white p-2"
><List
:grid="{ gutter: 5, xs: 1, sm: 2, md: 4, lg: 4, xl: 6, xxl: grid }"
:data-source="data"
:pagination="paginationProp"
>
<template #header>
<div class="flex justify-end space-x-2"
><slot name="header"></slot>
<Tooltip>
<template #title>
<div class="w-50">每行显示数量</div
><Slider
id="slider"
v-bind="sliderProp"
v-model:value="grid"
@change="sliderChange"
/></template>
<Button><TableOutlined /></Button>
</Tooltip>
<Tooltip @click="fetch">
<template #title>刷新</template>
<Button><RedoOutlined /></Button>
</Tooltip>
</div>
</template>
<template #renderItem="{ item }">
<ListItem>
<Card>
<template #title></template>
<template #cover>
<div :class="height">
<Image :src="item.imgs[0]" />
</div>
</template>
<template class="ant-card-actions" #actions>
<!-- <SettingOutlined key="setting" />-->
<EditOutlined key="edit" />
<Dropdown
:trigger="['hover']"
:dropMenuList="[
{
text: '删除',
event: '1',
popConfirm: {
title: '是否确认删除',
confirm: handleDelete.bind(null, item.id),
},
},
]"
popconfirm
>
<EllipsisOutlined key="ellipsis" />
</Dropdown>
</template>
<CardMeta>
<template #title>
<TypographyText :content="item.name" :ellipsis="{ tooltip: item.address }" />
</template>
<template #avatar>
<Avatar :src="item.avatar" />
</template>
<template #description>{{ item.time }}</template>
</CardMeta>
</Card>
</ListItem>
</template>
</List></div
>
</div>
</template>
<script lang="ts" setup>
import { computed, onMounted, ref } from 'vue';
import {
EditOutlined,
EllipsisOutlined,
RedoOutlined,
TableOutlined,
} from '@ant-design/icons-vue';
import {
List,
ListItem,
Card,
CardMeta,
Image,
TypographyText,
Tooltip,
Slider,
Avatar,
} from 'ant-design-vue';
import { Dropdown } from '/@/components/Dropdown';
import { BasicForm, useForm } from '/@/components/Form';
import { propTypes } from '/@/utils/propTypes';
import { Button } from '/@/components/Button';
import { isFunction } from '/@/utils/is';
import { useSlider, grid } from './data';
// slider
const sliderProp = computed(() => useSlider(4));
//
const props = defineProps({
// API
params: propTypes.object.def({}),
//api
api: propTypes.func,
});
//
const emit = defineEmits(['getMethod', 'delete']);
//
const data = ref([]);
//
// cover
//pageSize
const height = computed(() => {
return `h-${120 - grid.value * 6}`;
});
//
const [registerForm, { validate }] = useForm({
schemas: [{ field: 'type', component: 'Input', label: '类型' }],
labelWidth: 80,
baseColProps: { span: 6 },
actionColOptions: { span: 24 },
autoSubmitOnEnter: true,
submitFunc: handleSubmit,
});
//
async function handleSubmit() {
const data = await validate();
await fetch(data);
}
function sliderChange(n) {
pageSize.value = n * 4;
fetch();
}
//
onMounted(() => {
fetch();
emit('getMethod', fetch);
});
async function fetch(p = {}) {
const { api, params } = props;
if (api && isFunction(api)) {
const res = await api({ ...params, page: page.value, pageSize: pageSize.value, ...p });
data.value = res.items;
total.value = res.total;
}
}
//
const page = ref(1);
const pageSize = ref(36);
const total = ref(0);
const paginationProp = ref({
showSizeChanger: false,
showQuickJumper: true,
pageSize,
current: page,
total,
showTotal: (total) => `${total}`,
onChange: pageChange,
onShowSizeChange: pageSizeChange,
});
function pageChange(p, pz) {
page.value = p;
pageSize.value = pz;
fetch();
}
function pageSizeChange(current, size) {
pageSize.value = size;
fetch();
}
async function handleDelete(id) {
emit('delete', id);
}
</script>

View File

@ -0,0 +1,25 @@
import { ref } from 'vue';
//每行个数
export const grid = ref(12);
// slider属性
export const useSlider = (min = 6, max = 12) => {
// 每行显示个数滑动条
const getMarks = () => {
const l = {};
for (let i = min; i < max + 1; i++) {
l[i] = {
style: {
color: '#fff',
},
label: i,
};
}
return l;
};
return {
min,
max,
marks: getMarks(),
step: 1,
};
};

View File

@ -45,6 +45,7 @@ export default {
time: 'Relative Time',
cropperImage: 'Cropper Image',
cardList: 'Card List',
},
editor: {
editor: 'Editor',

View File

@ -44,6 +44,7 @@ export default {
time: '相对时间',
cropperImage: '图片裁剪',
cardList: '卡片列表',
},
editor: {
editor: '编辑器',

View File

@ -534,6 +534,14 @@ const comp: AppRouteModule = {
title: t('routes.demo.comp.loading'),
},
},
{
path: 'cardList',
name: 'CardListDemo',
component: () => import('/@/views/demo/comp/card-list/index.vue'),
meta: {
title: t('routes.demo.comp.cardList'),
},
},
],
};

View File

@ -0,0 +1,32 @@
<template>
<PageWrapper title="卡片列表示例" content="基础封装">
<CardList :params="params" :api="demoListApi" @getMethod="getMethod" @delete="handleDel">
<template #header>
<Button type="primary" color="error"> 按钮1 </Button>
<Button type="primary" color="success"> 按钮2 </Button>
</template>
</CardList>
</PageWrapper>
</template>
<script lang="ts" setup>
import { CardList } from '/@/components/CardList';
import { Button } from '/@/components/Button';
import { PageWrapper } from '/@/components/Page';
import { demoListApi } from '/@/api/demo/table';
import { useMessage } from '/@/hooks/web/useMessage';
const { notification } = useMessage();
// api
const params = {};
let reload = () => {};
// fetch;
function getMethod(m: any) {
reload = m;
}
//
function handleDel(id) {
console.log(id);
notification.success({ message: `成功删除${id}` });
reload();
}
</script>