fix: table actions

This commit is contained in:
100011797 2023-01-12 18:23:53 +08:00
parent 853331f4b4
commit 20061fb499
3 changed files with 174 additions and 104 deletions

View File

@ -54,31 +54,24 @@
delete: item.key === 'delete', delete: item.key === 'delete',
}" }"
> >
<!-- <slot name="actions" v-bind="item"></slot> -->
<a-popconfirm v-if="item.popConfirm" v-bind="item.popConfirm"> <a-popconfirm v-if="item.popConfirm" v-bind="item.popConfirm">
<template v-if="item.key === 'delete'">
<a-button :disabled="item.disabled"> <a-button :disabled="item.disabled">
<DeleteOutlined /> <DeleteOutlined v-if="item.key === 'delete'" />
</a-button>
</template>
<template v-else> <template v-else>
<a-button :disabled="item.disabled">
<AIcon :type="item.icon" /> <AIcon :type="item.icon" />
<span>{{ item.text }}</span> <span>{{ item.text }}</span>
</a-button>
</template> </template>
</a-button>
</a-popconfirm> </a-popconfirm>
<template v-else> <template v-else>
<template v-if="item.key === 'delete'">
<a-button :disabled="item.disabled"> <a-button :disabled="item.disabled">
<DeleteOutlined /> <DeleteOutlined v-if="item.key === 'delete'" />
</a-button>
</template>
<template v-else> <template v-else>
<a-button :disabled="item.disabled">
<AIcon :type="item.icon" /> <AIcon :type="item.icon" />
<span>{{ item.text }}</span> <span>{{ item.text }}</span>
</a-button>
</template> </template>
</a-button>
</template> </template>
</div> </div>
</div> </div>
@ -291,10 +284,10 @@ const handleClick = () => {
display: flex; display: flex;
flex-grow: 1; flex-grow: 1;
> span, & > span,
& button { button {
width: 100%; width: 100% !important;
border-radius: 0; border-radius: 0 !important;
} }
button { button {
@ -372,9 +365,9 @@ const handleClick = () => {
} }
} }
:deep(.ant-tooltip-disabled-compatible-wrapper) { // :deep(.ant-tooltip-disabled-compatible-wrapper) {
width: 100%; // width: 100%;
} // }
} }
} }
} }

View File

@ -50,11 +50,20 @@ export interface JTableProps extends TableProps{
pageIndex: number; pageIndex: number;
}; };
model?: keyof typeof ModelEnum | undefined; // 显示table还是card model?: keyof typeof ModelEnum | undefined; // 显示table还是card
actions?: ActionsType[]; // actions?: ActionsType[];
noPagination?: boolean; noPagination?: boolean;
rowSelection?: TableProps['rowSelection']; rowSelection?: TableProps['rowSelection'];
cardProps?: Record<string, any>; cardProps?: Record<string, any>;
dataSource?: Record<string, any>[]; dataSource?: Record<string, any>[];
gridColumn: number;
/**
*
* gridColumns[0] 1366 ~ 1440
* gridColumns[1] 1440 ~ 1600
* gridColumns[2] > 1600
*/
gridColumns?: number[];
alertRender?: boolean;
} }
const JTable = defineComponent<JTableProps>({ const JTable = defineComponent<JTableProps>({
@ -87,10 +96,10 @@ const JTable = defineComponent<JTableProps>({
type: [String, undefined], type: [String, undefined],
default: undefined default: undefined
}, },
actions: { // actions: {
type: Array as PropType<ActionsType[]>, // type: Array as PropType<ActionsType[]>,
default: () => [] // default: () => []
}, // },
noPagination: { noPagination: {
type: Boolean, type: Boolean,
default: false default: false
@ -106,12 +115,24 @@ const JTable = defineComponent<JTableProps>({
dataSource: { dataSource: {
type: Array, type: Array,
default: () => [] default: () => []
},
gridColumns: {
type: Array as PropType<Number[]>,
default: [2, 3, 4]
},
gridColumn: {
type: Number,
default: 4
},
alertRender: {
type: Boolean,
default: true
} }
} as any, } as any,
setup(props: JTableProps ,{ slots, emit }){ setup(props: JTableProps ,{ slots, emit }){
const simpleImage = Empty.PRESENTED_IMAGE_SIMPLE const simpleImage = Empty.PRESENTED_IMAGE_SIMPLE
const _model = ref<keyof typeof ModelEnum>(props.model ? props.model : ModelEnum.CARD); // 模式切换 const _model = ref<keyof typeof ModelEnum>(props.model ? props.model : ModelEnum.CARD); // 模式切换
const column = ref<number>(4); const column = ref<number>(props.gridColumn || 4);
const _dataSource = ref<Record<string, any>[]>([]) const _dataSource = ref<Record<string, any>[]>([])
const pageIndex = ref<number>(0) const pageIndex = ref<number>(0)
const pageSize = ref<number>(6) const pageSize = ref<number>(6)
@ -119,9 +140,20 @@ const JTable = defineComponent<JTableProps>({
const _columns = ref<JColumnProps[]>(props?.columns || []) const _columns = ref<JColumnProps[]>(props?.columns || [])
const loading = ref<boolean>(true) const loading = ref<boolean>(true)
// alert关闭取消选择 /**
const handleAlertClose = () => { *
emit('cancelSelect') */
const windowChange = () => {
if (window.innerWidth <= 1440) {
const _column = props.gridColumn && props.gridColumn < 2 ? props.gridColumn : 2;
column.value = props.gridColumns ? props.gridColumns[0] : _column
} else if (window.innerWidth > 1440 && window.innerWidth <= 1600) {
const _column = props.gridColumn && props.gridColumn < 3 ? props.gridColumn : 3;
column.value = props.gridColumns ? props.gridColumns[1] : _column
} else if (window.innerWidth > 1600) {
const _column = props.gridColumn && props.gridColumn < 4 ? props.gridColumn : 4;
column.value = props.gridColumns ? props.gridColumns[2] : _column
}
} }
/** /**
@ -153,7 +185,6 @@ const JTable = defineComponent<JTableProps>({
} else { } else {
_dataSource.value = props?.dataSource || [] _dataSource.value = props?.dataSource || []
} }
loading.value = false loading.value = false
} }
@ -161,6 +192,16 @@ const JTable = defineComponent<JTableProps>({
handleSearch(props.params) handleSearch(props.params)
}) })
onMounted(() => {
window.onresize = () => {
windowChange()
}
})
onUnmounted(() => {
window.onresize = null
})
return () => <Spin spinning={loading.value}> return () => <Spin spinning={loading.value}>
<div class={styles["jtable-body"]}> <div class={styles["jtable-body"]}>
<div class={styles["jtable-body-header"]}> <div class={styles["jtable-body-header"]}>
@ -184,12 +225,14 @@ const JTable = defineComponent<JTableProps>({
{/* content */} {/* content */}
<div class={styles['jtable-content']}> <div class={styles['jtable-content']}>
{ {
props?.rowSelection && props?.rowSelection?.selectedRowKeys && props.rowSelection.selectedRowKeys?.length ? props.alertRender && props?.rowSelection && props?.rowSelection?.selectedRowKeys && props.rowSelection.selectedRowKeys?.length ?
<div class={styles['jtable-alert']}> <div class={styles['jtable-alert']}>
<Alert <Alert
message={'已选择' + props?.rowSelection?.selectedRowKeys?.length + '项'} message={'已选择' + props?.rowSelection?.selectedRowKeys?.length + '项'}
type="info" type="info"
onClose={handleAlertClose} onClose={() => {
emit('cancelSelect')
}}
closeText={<a></a>} closeText={<a></a>}
/> />
</div> : null </div> : null
@ -205,8 +248,10 @@ const JTable = defineComponent<JTableProps>({
> >
{ {
_dataSource.value.map(item => slots.card ? _dataSource.value.map(item => slots.card ?
<div class={[styles['jtable-card-item'], props.cardBodyClass]}>{slots.card({row: item, actions: props?.actions || []})}</div> <div class={[styles['jtable-card-item'], props.cardBodyClass]}>
: null) {slots.card(item)}
</div> : null
)
} }
</div> : </div> :
<div><Empty image={Empty.PRESENTED_IMAGE_SIMPLE} /></div> <div><Empty image={Empty.PRESENTED_IMAGE_SIMPLE} /></div>
@ -225,7 +270,7 @@ const JTable = defineComponent<JTableProps>({
const {column, record} = dt; const {column, record} = dt;
if((column?.key || column?.dataIndex) && column?.scopedSlots && (slots?.[column?.dataIndex] || slots?.[column?.key])) { if((column?.key || column?.dataIndex) && column?.scopedSlots && (slots?.[column?.dataIndex] || slots?.[column?.key])) {
const _key = column?.key || column?.dataIndex const _key = column?.key || column?.dataIndex
return slots?.[_key]!({row: record, actions: props.actions}) return slots?.[_key]!(record)
} else { } else {
return record?.[column?.dataIndex] || '' return record?.[column?.dataIndex] || ''
} }

View File

@ -1,7 +1,92 @@
<template> <template>
<div class="box"> <div class="box">
<JTable <JTable
:columns="[ :columns="columns"
:request="request"
:rowSelection="{
selectedRowKeys: _selectedRowKeys,
onChange: onSelectChange
}"
@cancelSelect="cancelSelect"
>
<template #headerTitle>
<a-button type="primary">新增</a-button>
</template>
<template #card="slotProps">
<CardBox
:value="slotProps"
@click="handleClick"
:actions="getActions(slotProps)"
v-bind="slotProps"
:active="_selectedRowKeys.includes(slotProps.id)"
:status="slotProps.state ? 'success' : 'error'"
>
<template #img>
<slot name="img">
<img :src="getImage('/device-product.png')" />
</slot>
</template>
<template #content>
<h3>{{slotProps.name}}</h3>
<a-row>
<a-col :span="12">
<div class="card-item-content-text">
设备类型
</div>
<div>直连设备</div>
</a-col>
</a-row>
</template>
<!-- <template #actions="item">
<a-popconfirm v-if="item.popConfirm" v-bind="item.popConfirm">
<a-button :disabled="item.disabled">
<DeleteOutlined v-if="item.key === 'delete'" />
<template v-else>
<AIcon :type="item.icon" />
<span>{{ item.text }}</span>
</template>
</a-button>
</a-popconfirm>
<template v-else>
<a-button :disabled="item.disabled">
<DeleteOutlined v-if="item.key === 'delete'" />
<template v-else>
<AIcon :type="item.icon" />
<span>{{ item.text }}</span>
</template>
</a-button>
</template>
</template> -->
</CardBox>
</template>
<template #id="slotProps">
<a>{{slotProps.id}}</a>
</template>
<template #action="slotProps">
<a-space :size="16">
<a-tooltip v-for="i in getActions(slotProps)" :key="i.key" v-bind="i.tooltip">
<a-popconfirm v-if="i.popConfirm" v-bind="i.popConfirm">
<a-button :disabled="i.disabled" style="padding: 0" type="link"><AIcon :type="i.icon" /></a-button>
</a-popconfirm>
<a-button style="padding: 0" type="link" v-else @click="i.onClick && i.onClick(slotProps)">
<a-button :disabled="i.disabled" style="padding: 0" type="link"><AIcon :type="i.icon" /></a-button>
</a-button>
</a-tooltip>
</a-space>
</template>
</JTable>
</div>
</template>
<script setup lang="ts">
import server from "@/utils/request";
import type { ActionsType } from '@/components/Table/index.vue'
import { getImage } from '@/utils/comm';
import { DeleteOutlined } from '@ant-design/icons-vue'
const request = (data: any) => server.post(`/device-product/_query`, data)
const columns = [
{ {
title: '名称', title: '名称',
dataIndex: 'name', dataIndex: 'name',
@ -25,99 +110,6 @@
width: 250, width: 250,
scopedSlots: true scopedSlots: true
} }
]"
:actions="actions"
:request="request"
:rowSelection="{
selectedRowKeys: _selectedRowKeys,
onChange: onSelectChange
}"
@cancelSelect="cancelSelect"
>
<template #headerTitle>
<a-button type="primary">新增</a-button>
</template>
<template #card="slotProps">
<CardBox :value="slotProps" @click="handleClick" :actions="slotProps.actions" v-bind="slotProps.row" :active="_selectedRowKeys.includes(slotProps.row.id)">
<template #img>
<slot name="img">
<img :src="getImage('/device-product.png')" />
</slot>
</template>
<template #content>
<h3>{{slotProps.row.name}}</h3>
<a-row>
<a-col :span="12">
<div class="card-item-content-text">
设备类型
</div>
<div>直连设备</div>
</a-col>
<a-col :span="12">
<div class="card-item-content-text">
产品名称
</div>
<div>测试固定地址</div>
</a-col>
</a-row>
</template>
</CardBox>
</template>
<template #id="slotProps">
<a>{{slotProps.row.id}}</a>
</template>
<template #action="slotProps">
<a-space :size="16">
<a-tooltip v-for="i in slotProps.actions" :key="i.key" v-bind="i.tooltip">
<a-popconfirm v-if="i.popConfirm" v-bind="i.popConfirm">
<a-button style="padding: 0" type="link"><AIcon :type="i.icon" /></a-button>
</a-popconfirm>
<a-button style="padding: 0" type="link" v-else @click="i.onClick && i.onClick(slotProps.row)">
<AIcon :type="i.icon" />
</a-button>
</a-tooltip>
</a-space>
</template>
</JTable>
</div>
</template>
<script setup lang="ts">
import server from "@/utils/request";
import type { ActionsType } from '@/components/Table/index.vue'
import { getImage } from '@/utils/comm';
const request = (data: any) => server.post(`/device-product/_query`, data)
const actions: ActionsType[] = [
{
key: 'edit',
// disabled: true,
text: "编辑",
tooltip: {
title: '编辑'
},
icon: 'icon-rizhifuwu'
},
{
key: 'import',
// disabled: true,
text: "导入",
tooltip: {
title: '导入'
},
icon: 'icon-xiazai'
},
{
key: 'delete',
// disabled: true,
text: "删除",
tooltip: {
title: '删除'
},
popConfirm: {
title: '确认删除?'
},
}
] ]
const _selectedRowKeys = ref<string[]>([]) const _selectedRowKeys = ref<string[]>([])
@ -141,6 +133,46 @@ const handleClick = (dt: any) => {
} }
} }
const getActions = (data: Partial<Record<string, any>>): ActionsType[] => {
if(!data){
return []
}
return [
{
key: 'edit',
text: "编辑",
tooltip: {
title: '编辑'
},
icon: 'icon-rizhifuwu'
},
{
key: 'import',
text: "导入",
tooltip: {
title: '导入'
},
icon: 'icon-xiazai'
},
{
key: 'delete',
// disabled: true,
text: "删除",
disabled: !!data?.state,
tooltip: {
title: !!data?.state ? '正常的产品不能删除' : '删除'
},
// popConfirm: {
// title: '?'
// },
icon: 'icon-huishouzhan'
}
]
}
const p = h('p', 'hi')
</script> </script>