perf: #344
This commit is contained in:
parent
2f6483652b
commit
7fa533b8ba
|
@ -158,6 +158,14 @@ const adminList = [
|
||||||
meta: {
|
meta: {
|
||||||
title: 'router.tableVideoPreview'
|
title: 'router.tableVideoPreview'
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'card-table',
|
||||||
|
component: 'views/Components/Table/CardTable',
|
||||||
|
name: 'CardTable',
|
||||||
|
meta: {
|
||||||
|
title: 'router.cardTable'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// {
|
// {
|
||||||
// path: 'ref-table',
|
// path: 'ref-table',
|
||||||
|
@ -659,6 +667,7 @@ const testList: string[] = [
|
||||||
'/components/table/table-image-preview',
|
'/components/table/table-image-preview',
|
||||||
'/components/table/table-video-preview',
|
'/components/table/table-video-preview',
|
||||||
'/components/table/ref-table',
|
'/components/table/ref-table',
|
||||||
|
'/components/table/card-table',
|
||||||
'/components/editor-demo',
|
'/components/editor-demo',
|
||||||
'/components/editor-demo/editor',
|
'/components/editor-demo/editor',
|
||||||
'/components/editor-demo/json-editor',
|
'/components/editor-demo/json-editor',
|
||||||
|
|
|
@ -176,6 +176,39 @@ for (let i = 0; i < count; i++) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const cardList = [
|
||||||
|
{
|
||||||
|
logo: 'https://gw.alipayobjects.com/zos/rmsportal/WdGqmHpayyMjiEhcKoVE.png',
|
||||||
|
name: 'Alipay',
|
||||||
|
desc: '在中台产品的研发过程中,会出现不同的设计规范和实现方式,但其中往往存在很多类似的页面和组件,这些类似的组件会被抽离成一套标准规范。'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
logo: 'https://gw.alipayobjects.com/zos/rmsportal/zOsKZmFRdUtvpqCImOVY.png',
|
||||||
|
name: 'Angular',
|
||||||
|
desc: '在中台产品的研发过程中,会出现不同的设计规范和实现方式,但其中往往存在很多类似的页面和组件,这些类似的组件会被抽离成一套标准规范。'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
logo: 'https://gw.alipayobjects.com/zos/rmsportal/siCrBXXhmvTQGWPNLBow.png',
|
||||||
|
name: 'Bootstrap',
|
||||||
|
desc: '在中台产品的研发过程中,会出现不同的设计规范和实现方式,但其中往往存在很多类似的页面和组件,这些类似的组件会被抽离成一套标准规范。'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
logo: 'https://gw.alipayobjects.com/zos/rmsportal/kZzEzemZyKLKFsojXItE.png',
|
||||||
|
name: 'React',
|
||||||
|
desc: '在中台产品的研发过程中,会出现不同的设计规范和实现方式,但其中往往存在很多类似的页面和组件,这些类似的组件会被抽离成一套标准规范。'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
logo: 'https://gw.alipayobjects.com/zos/rmsportal/ComBAopevLwENQdKWiIn.png',
|
||||||
|
name: 'Vue',
|
||||||
|
desc: '在中台产品的研发过程中,会出现不同的设计规范和实现方式,但其中往往存在很多类似的页面和组件,这些类似的组件会被抽离成一套标准规范。'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
logo: 'https://gw.alipayobjects.com/zos/rmsportal/nxkuOJlFJuAUhzlMTCEe.png',
|
||||||
|
name: 'Webpack',
|
||||||
|
desc: '在中台产品的研发过程中,会出现不同的设计规范和实现方式,但其中往往存在很多类似的页面和组件,这些类似的组件会被抽离成一套标准规范。'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
export default [
|
export default [
|
||||||
// 树形列表接口
|
// 树形列表接口
|
||||||
{
|
{
|
||||||
|
@ -294,5 +327,27 @@ export default [
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: '/mock/card/list',
|
||||||
|
method: 'GET',
|
||||||
|
delay,
|
||||||
|
body: ({ query }) => {
|
||||||
|
const { name, pageIndex, pageSize } = query
|
||||||
|
const mockList = cardList.filter((item) => {
|
||||||
|
if (name && item.name.indexOf(name) < 0) return false
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
const pageList = mockList.filter(
|
||||||
|
(_, index) => index < pageSize * pageIndex && index >= pageSize * (pageIndex - 1)
|
||||||
|
)
|
||||||
|
return {
|
||||||
|
code: SUCCESS_CODE,
|
||||||
|
data: {
|
||||||
|
total: mockList.length,
|
||||||
|
list: pageList
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -5,6 +5,10 @@ export const getTableListApi = (params: any) => {
|
||||||
return request.get({ url: '/mock/example/list', params })
|
return request.get({ url: '/mock/example/list', params })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const getCardTableListApi = (params: any) => {
|
||||||
|
return request.get({ url: '/mock/card/list', params })
|
||||||
|
}
|
||||||
|
|
||||||
export const getTreeTableListApi = (params: any) => {
|
export const getTreeTableListApi = (params: any) => {
|
||||||
return request.get({ url: '/mock/example/treeList', params })
|
return request.get({ url: '/mock/example/treeList', params })
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,9 @@ import {
|
||||||
ComponentSize,
|
ComponentSize,
|
||||||
ElTooltipProps,
|
ElTooltipProps,
|
||||||
ElImage,
|
ElImage,
|
||||||
ElButton
|
ElButton,
|
||||||
|
ElEmpty,
|
||||||
|
ElCard
|
||||||
} from 'element-plus'
|
} from 'element-plus'
|
||||||
import { defineComponent, PropType, ref, computed, unref, watch, onMounted } from 'vue'
|
import { defineComponent, PropType, ref, computed, unref, watch, onMounted } from 'vue'
|
||||||
import { propTypes } from '@/utils/propTypes'
|
import { propTypes } from '@/utils/propTypes'
|
||||||
|
@ -185,7 +187,25 @@ export default defineComponent({
|
||||||
default: 'fixed'
|
default: 'fixed'
|
||||||
},
|
},
|
||||||
scrollbarAlwaysOn: propTypes.bool.def(false),
|
scrollbarAlwaysOn: propTypes.bool.def(false),
|
||||||
flexible: propTypes.bool.def(false)
|
flexible: propTypes.bool.def(false),
|
||||||
|
// 自定义内容
|
||||||
|
customContent: propTypes.bool.def(false),
|
||||||
|
cardBodyStyle: {
|
||||||
|
type: Object as PropType<CSSProperties>,
|
||||||
|
default: () => ({})
|
||||||
|
},
|
||||||
|
cardBodyClass: {
|
||||||
|
type: String as PropType<string>,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
cardWrapStyle: {
|
||||||
|
type: Object as PropType<CSSProperties>,
|
||||||
|
default: () => ({})
|
||||||
|
},
|
||||||
|
cardWrapClass: {
|
||||||
|
type: String as PropType<string>,
|
||||||
|
default: ''
|
||||||
|
}
|
||||||
},
|
},
|
||||||
emits: ['update:pageSize', 'update:currentPage', 'register', 'refresh'],
|
emits: ['update:pageSize', 'update:currentPage', 'register', 'refresh'],
|
||||||
setup(props, { attrs, emit, slots, expose }) {
|
setup(props, { attrs, emit, slots, expose }) {
|
||||||
|
@ -484,6 +504,45 @@ export default defineComponent({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div v-loading={unref(getProps).loading}>
|
<div v-loading={unref(getProps).loading}>
|
||||||
|
{unref(getProps).customContent ? (
|
||||||
|
<div class="flex flex-wrap">
|
||||||
|
{unref(getProps)?.data?.length ? (
|
||||||
|
unref(getProps)?.data.map((item) => {
|
||||||
|
const cardSlots = {
|
||||||
|
default: () => {
|
||||||
|
return getSlot(slots, 'content', item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (getSlot(slots, 'content-header')) {
|
||||||
|
cardSlots['header'] = () => {
|
||||||
|
return getSlot(slots, 'content-header', item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (getSlot(slots, 'content-footer')) {
|
||||||
|
cardSlots['footer'] = () => {
|
||||||
|
return getSlot(slots, 'content-footer', item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<ElCard
|
||||||
|
shadow="hover"
|
||||||
|
class={unref(getProps).cardWrapClass}
|
||||||
|
style={unref(getProps).cardWrapStyle}
|
||||||
|
bodyClass={unref(getProps).cardBodyClass}
|
||||||
|
bodyStyle={unref(getProps).cardBodyStyle}
|
||||||
|
>
|
||||||
|
{cardSlots}
|
||||||
|
</ElCard>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
) : (
|
||||||
|
<div class="flex flex-1 justify-center">
|
||||||
|
<ElEmpty description="暂无数据" />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
{unref(getProps).showAction ? (
|
{unref(getProps).showAction ? (
|
||||||
<TableActions
|
<TableActions
|
||||||
columns={unref(getProps).columns}
|
columns={unref(getProps).columns}
|
||||||
|
@ -497,6 +556,8 @@ export default defineComponent({
|
||||||
...tableSlots
|
...tableSlots
|
||||||
}}
|
}}
|
||||||
</ElTable>
|
</ElTable>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
{unref(getProps).pagination ? (
|
{unref(getProps).pagination ? (
|
||||||
<ElPagination
|
<ElPagination
|
||||||
v-model:pageSize={pageSizeRef.value}
|
v-model:pageSize={pageSizeRef.value}
|
||||||
|
|
|
@ -181,7 +181,8 @@ export default {
|
||||||
imageCropping: 'Image cropping',
|
imageCropping: 'Image cropping',
|
||||||
videoPlayer: 'Video player',
|
videoPlayer: 'Video player',
|
||||||
// 表格视频预览
|
// 表格视频预览
|
||||||
tableVideoPreview: 'Table video preview'
|
tableVideoPreview: 'Table video preview',
|
||||||
|
cardTable: 'Card table'
|
||||||
},
|
},
|
||||||
permission: {
|
permission: {
|
||||||
hasPermission: 'Please set the operation permission value'
|
hasPermission: 'Please set the operation permission value'
|
||||||
|
@ -457,7 +458,8 @@ export default {
|
||||||
getSelections: 'Get selections',
|
getSelections: 'Get selections',
|
||||||
preview: 'Preview',
|
preview: 'Preview',
|
||||||
showOrHiddenSortable: 'Show or hidden sortable',
|
showOrHiddenSortable: 'Show or hidden sortable',
|
||||||
videoPreview: 'Video preview'
|
videoPreview: 'Video preview',
|
||||||
|
cardTable: 'Card table'
|
||||||
},
|
},
|
||||||
richText: {
|
richText: {
|
||||||
richText: 'Rich text',
|
richText: 'Rich text',
|
||||||
|
|
|
@ -178,7 +178,8 @@ export default {
|
||||||
waterfall: '瀑布流',
|
waterfall: '瀑布流',
|
||||||
imageCropping: '图片裁剪',
|
imageCropping: '图片裁剪',
|
||||||
videoPlayer: '视频播放器',
|
videoPlayer: '视频播放器',
|
||||||
tableVideoPreview: '表格视频预览'
|
tableVideoPreview: '表格视频预览',
|
||||||
|
cardTable: '卡片表格'
|
||||||
},
|
},
|
||||||
permission: {
|
permission: {
|
||||||
hasPermission: '请设置操作权限值'
|
hasPermission: '请设置操作权限值'
|
||||||
|
@ -449,7 +450,8 @@ export default {
|
||||||
getSelections: '获取多选数据',
|
getSelections: '获取多选数据',
|
||||||
preview: '封面',
|
preview: '封面',
|
||||||
showOrHiddenSortable: '显示/隐藏排序',
|
showOrHiddenSortable: '显示/隐藏排序',
|
||||||
videoPreview: '视频预览'
|
videoPreview: '视频预览',
|
||||||
|
cardTable: '卡片表格'
|
||||||
},
|
},
|
||||||
richText: {
|
richText: {
|
||||||
richText: '富文本',
|
richText: '富文本',
|
||||||
|
|
|
@ -209,6 +209,14 @@ export const asyncRouterMap: AppRouteRecordRaw[] = [
|
||||||
meta: {
|
meta: {
|
||||||
title: t('router.tableVideoPreview')
|
title: t('router.tableVideoPreview')
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'card-table',
|
||||||
|
component: () => import('@/views/Components/Table/CardTable.vue'),
|
||||||
|
name: 'CardTable',
|
||||||
|
meta: {
|
||||||
|
title: t('router.cardTable')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
<script setup lang="tsx">
|
||||||
|
import { ContentWrap } from '@/components/ContentWrap'
|
||||||
|
import { useI18n } from '@/hooks/web/useI18n'
|
||||||
|
import { Table } from '@/components/Table'
|
||||||
|
import { getCardTableListApi } from '@/api/table'
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import { ElLink, ElDivider } from 'element-plus'
|
||||||
|
|
||||||
|
interface Params {
|
||||||
|
pageIndex?: number
|
||||||
|
pageSize?: number
|
||||||
|
}
|
||||||
|
|
||||||
|
const { t } = useI18n()
|
||||||
|
|
||||||
|
const loading = ref(true)
|
||||||
|
|
||||||
|
let tableDataList = ref<any[]>([])
|
||||||
|
|
||||||
|
const getTableList = async (params?: Params) => {
|
||||||
|
const res = await getCardTableListApi(
|
||||||
|
params || {
|
||||||
|
pageIndex: 1,
|
||||||
|
pageSize: 10
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.catch(() => {})
|
||||||
|
.finally(() => {
|
||||||
|
loading.value = false
|
||||||
|
})
|
||||||
|
if (res) {
|
||||||
|
tableDataList.value = res.data.list
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getTableList()
|
||||||
|
|
||||||
|
const actionClick = (row?: any) => {
|
||||||
|
console.log(row)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<ContentWrap :title="t('tableDemo.cardTable')">
|
||||||
|
<Table
|
||||||
|
:columns="[]"
|
||||||
|
:data="tableDataList"
|
||||||
|
:loading="loading"
|
||||||
|
custom-content
|
||||||
|
:card-wrap-style="{
|
||||||
|
width: '200px',
|
||||||
|
marginBottom: '20px',
|
||||||
|
marginRight: '20px'
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<template #content="row">
|
||||||
|
<div class="flex cursor-pointer">
|
||||||
|
<div class="pr-16px">
|
||||||
|
<img :src="row.logo" class="w-48px h-48px rounded-[50%]" alt="" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div class="mb-12px font-700 font-size-16px">{{ row.name }}</div>
|
||||||
|
<div class="line-clamp-3 font-size-12px">{{ row.desc }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template #content-footer="item">
|
||||||
|
<div class="flex justify-center items-center">
|
||||||
|
<div class="flex-1 text-center" @click="() => actionClick(item)">
|
||||||
|
<ElLink :underline="false">操作一</ElLink>
|
||||||
|
</div>
|
||||||
|
<ElDivider direction="vertical" />
|
||||||
|
<div class="flex-1 text-center" @click="() => actionClick(item)">
|
||||||
|
<ElLink :underline="false">操作二</ElLink>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</Table>
|
||||||
|
</ContentWrap>
|
||||||
|
</template>
|
Loading…
Reference in New Issue