feat: table
This commit is contained in:
parent
81c27df227
commit
be792dd961
|
@ -11,6 +11,8 @@ node_modules
|
|||
dist
|
||||
dist-ssr
|
||||
*.local
|
||||
yarn.lock
|
||||
components.d.ts
|
||||
|
||||
# Editor directories and files
|
||||
.vscode
|
||||
|
|
|
@ -18,6 +18,8 @@ declare module '@vue/runtime-core' {
|
|||
AInputPassword: typeof import('ant-design-vue/es')['InputPassword']
|
||||
AModal: typeof import('ant-design-vue/es')['Modal']
|
||||
APopconfirm: typeof import('ant-design-vue/es')['Popconfirm']
|
||||
ACard: typeof import('ant-design-vue/es')['Card']
|
||||
ACol: typeof import('ant-design-vue/es')['Col']
|
||||
ARow: typeof import('ant-design-vue/es')['Row']
|
||||
ASelect: typeof import('ant-design-vue/es')['Select']
|
||||
ASpin: typeof import('ant-design-vue/es')['Spin']
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
.jtable-body {
|
||||
width: 100%;
|
||||
padding: 0 24px 24px;
|
||||
background-color: white;
|
||||
.jtable-body-header {
|
||||
padding: 16px 0;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
.jtable-body-header-right {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
.jtable-setting-item {
|
||||
color: rgba(0, 0, 0, 0.75);
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
color: @primary-color-hover;
|
||||
}
|
||||
|
||||
&.active {
|
||||
color: @primary-color-active;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.jtable-content {
|
||||
.jtable-card {
|
||||
.jtable-card-items {
|
||||
display: grid;
|
||||
grid-gap: 26px;
|
||||
// grid-template-columns: repeat(4, 1fr);
|
||||
.jtable-card-item {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.jtable-pagination {
|
||||
position: absolute;
|
||||
right: 24px;
|
||||
bottom: 24px;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,163 @@
|
|||
import { UnorderedListOutlined, AppstoreOutlined } from '@ant-design/icons-vue'
|
||||
import styles from './index.module.less'
|
||||
import { Space, Pagination, Table, Empty } from 'ant-design-vue'
|
||||
import type { TableProps } from 'ant-design-vue/es/table'
|
||||
enum ModelEnum {
|
||||
TABLE = 'TABLE',
|
||||
CARD = 'CARD',
|
||||
}
|
||||
|
||||
export declare type RequestData = {
|
||||
code: string;
|
||||
result: {
|
||||
data: any[] | undefined;
|
||||
pageIndex: number;
|
||||
pageSize: number;
|
||||
total: number;
|
||||
};
|
||||
status: number;
|
||||
} & Record<string, any>;
|
||||
// interface ColumnType extends
|
||||
|
||||
interface JTableProps extends TableProps{
|
||||
// columns?: ColumnsType<RecordType>;
|
||||
request: (params: Record<string, any> & {
|
||||
pageSize?: number;
|
||||
pageIndex?: number;
|
||||
}) => Promise<Partial<RequestData>>;
|
||||
cardBodyClass?: string;
|
||||
}
|
||||
|
||||
|
||||
const JTable = defineComponent<JTableProps>({
|
||||
name: 'JTable',
|
||||
slots: [
|
||||
'headerTitle', // 顶部左边插槽
|
||||
'cardRender', // 卡片内容
|
||||
],
|
||||
emits: [
|
||||
'modelChange', // 切换卡片和表格
|
||||
],
|
||||
setup(props: JTableProps, { slots, emit }){
|
||||
const model = ref<keyof typeof ModelEnum>(ModelEnum.CARD); // 模式切换
|
||||
const column = ref<number>(3);
|
||||
console.log(props)
|
||||
const dataSource = ref<any[]>([
|
||||
{
|
||||
key: '1',
|
||||
name: '胡彦斌',
|
||||
age: 32,
|
||||
address: '西湖区湖底公园1号',
|
||||
},
|
||||
{
|
||||
key: '2',
|
||||
name: '胡彦祖1',
|
||||
age: 42,
|
||||
address: '西湖区湖底公园1号',
|
||||
},
|
||||
{
|
||||
key: '3',
|
||||
name: '胡彦斌',
|
||||
age: 32,
|
||||
address: '西湖区湖底公园1号',
|
||||
},
|
||||
{
|
||||
key: '4',
|
||||
name: '胡彦祖1',
|
||||
age: 42,
|
||||
address: '西湖区湖底公园1号',
|
||||
},
|
||||
{
|
||||
key: '5',
|
||||
name: '胡彦斌',
|
||||
age: 32,
|
||||
address: '西湖区湖底公园1号',
|
||||
},
|
||||
{
|
||||
key: '6',
|
||||
name: '胡彦祖1',
|
||||
age: 42,
|
||||
address: '西湖区湖底公园1号',
|
||||
},
|
||||
])
|
||||
|
||||
onMounted(() => {
|
||||
|
||||
})
|
||||
|
||||
return () => <div class={styles["jtable-body"]}>
|
||||
<div class={styles["jtable-body-header"]}>
|
||||
<div class={styles["jtable-body-header-left"]}>
|
||||
{/* 顶部左边插槽 */}
|
||||
{slots.headerTitle && slots.headerTitle()}
|
||||
</div>
|
||||
<div class={styles["jtable-body-header-right"]}>
|
||||
{/* <Space> */}
|
||||
<div class={[styles["jtable-setting-item"], ModelEnum.CARD === model.value ? styles['active'] : '']} onClick={() => {
|
||||
model.value = ModelEnum.CARD
|
||||
}}>
|
||||
<AppstoreOutlined />
|
||||
</div>
|
||||
<div class={[styles["jtable-setting-item"], ModelEnum.TABLE === model.value ? styles['active'] : '']} onClick={() => {
|
||||
model.value = ModelEnum.TABLE
|
||||
}}>
|
||||
<UnorderedListOutlined />
|
||||
</div>
|
||||
{/* </Space> */}
|
||||
</div>
|
||||
</div>
|
||||
{/* content */}
|
||||
<div class={styles['jtable-content']}>
|
||||
{
|
||||
model.value === ModelEnum.CARD ?
|
||||
<div class={styles['jtable-card']}>
|
||||
{
|
||||
dataSource.value.length ?
|
||||
<div
|
||||
class={styles['jtable-card-items']}
|
||||
style={{gridTemplateColumns: `repeat(${column.value}, 1fr)`}}
|
||||
>
|
||||
{
|
||||
dataSource.value.map(item => slots.cardRender ?
|
||||
<div class={[styles['jtable-card-item'], props.cardBodyClass]}>{slots.cardRender(item)}</div>
|
||||
: null)
|
||||
}
|
||||
</div> :
|
||||
<div><Empty image={Empty.PRESENTED_IMAGE_SIMPLE} /></div>
|
||||
}
|
||||
</div> :
|
||||
<div>
|
||||
<Table
|
||||
dataSource={dataSource.value}
|
||||
columns={props.columns}
|
||||
pagination={false}
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
{/* 分页 */}
|
||||
{
|
||||
dataSource.value.length &&
|
||||
<div class={styles['jtable-pagination']}>
|
||||
<Pagination
|
||||
size="small"
|
||||
total={50}
|
||||
showTotal={(total) => {
|
||||
const min = 1
|
||||
const max = 1
|
||||
return `第 ${min} - ${max} 条/总共 ${total} 条`
|
||||
}}
|
||||
onChange={() => {
|
||||
|
||||
}}
|
||||
onShowSizeChange={() => {
|
||||
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
})
|
||||
|
||||
export default JTable
|
|
@ -1,10 +1,12 @@
|
|||
import type { App } from 'vue'
|
||||
import AIcon from './AIcon'
|
||||
import PermissionButton from './PermissionButton/index.vue'
|
||||
import JTable from './Table/index'
|
||||
|
||||
export default {
|
||||
install(app: App) {
|
||||
app.component('AIcon', AIcon)
|
||||
app.component('PermissionButton', PermissionButton)
|
||||
app.component('JTable', JTable)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,6 +36,10 @@ export default [
|
|||
path: '/iot/home',
|
||||
component: () => import('@/views/iot/home/index.vue')
|
||||
},
|
||||
{
|
||||
path: '/table',
|
||||
component: () => import('@/views/table/index.vue')
|
||||
},
|
||||
// end: 测试用, 可删除
|
||||
|
||||
{
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
<template>
|
||||
<div class="box">
|
||||
<JTable
|
||||
:columns="[
|
||||
{
|
||||
title: '姓名',
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
},
|
||||
{
|
||||
title: '年龄',
|
||||
dataIndex: 'age',
|
||||
key: 'age',
|
||||
},
|
||||
{
|
||||
title: '住址',
|
||||
dataIndex: 'address',
|
||||
key: 'address',
|
||||
}
|
||||
]"
|
||||
>
|
||||
<template #headerTitle>
|
||||
<a-button type="primary">新增</a-button>
|
||||
</template>
|
||||
<template #cardRender="slotProps">
|
||||
{{slotProps.name}}
|
||||
</template>
|
||||
</JTable>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
</script>
|
||||
|
||||
|
||||
<style lang="less" scoped>
|
||||
.box {
|
||||
padding: 20px;
|
||||
background: #f0f2f5;
|
||||
}
|
||||
</style>
|
||||
|
Loading…
Reference in New Issue