消毒机设备
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

145 lines
3.0 KiB

<script setup lang="ts">
import type { VNode } from 'vue'
import { onMounted, reactive } from 'vue'
import Expand from './expand'
defineOptions({
name: 'FtTable',
})
const props = withDefaults(defineProps<TableProp>(), {
columns: () => [],
mustInit: true,
hasHeader: true,
getDataFn: () => Promise.resolve([]),
})
const emits = defineEmits([])
enum ColumnType {
index = 'index',
selection = 'selection',
expand = 'expand',
}
interface TableColumn {
title: string
key: string
type?: ColumnType
width?: number // 列宽
fixed?: 'left' | 'right' | undefined // 是否固定列
render?: (row: any) => VNode // 内容自定义
}
interface Btn {
name: string
icon?: string
type?: string
serverUrl: string
}
interface TableProp {
columns: TableColumn[]
getDataFn: (params: any) => Promise<any> // 表格数据的接口
mustInit?: boolean // 是否在mounted里执行getDataFn
hasHeader?: boolean
btnList?: Btn[]
}
// const attrs = useAttrs()
async function methodParent(fn: any) {
const newFn = fn[0] === '/' ? fn.slice(1) : fn
emits(newFn as never)
}
onMounted(() => {
if (props.mustInit) {
initData()
}
})
const state = reactive({
loading: false,
dataTotal: 0,
tableData: [],
})
function initData() {
state.loading = true
props
.getDataFn({})
.then((data) => {
console.log(data)
state.tableData = data
state.loading = false
})
.finally(() => {
state.loading = false
})
}
defineExpose({
initData,
})
</script>
<template>
<div v-if="hasHeader" class="header">
<div v-for="btn in btnList" :key="btn.serverUrl">
<el-button :icon="btn.icon" :type="btn.type" @click="methodParent(btn.serverUrl)">
{{ btn.name }}
</el-button>
</div>
<div class="search">
<el-input v-prevent-keyboard>
<template #suffix>
<el-icon class="el-input__icon">
<search />
</el-icon>
</template>
</el-input>
</div>
</div>
<el-table
v-loading="state.loading"
:="$attrs"
:data="state.tableData"
style="width: 100%"
height="100%"
:highlight-current-row="true"
class="container-table"
header-row-class-name="header-row-class"
>
<template v-for="(column, index) in columns" :key="column.key">
<el-table-column
show-overflow-tooltip
:prop="column.key"
:label="column.title"
:width="column.width"
:type="column.type"
:fixed="column.fixed"
>
<template v-if="column.render" #default="scope">
<Expand :column="column" :row="scope.row" :render="column.render" :index="index" />
</template>
</el-table-column>
</template>
</el-table>
</template>
<style lang="scss" scoped>
.header {
display: flex;
justify-content: space-between;
align-items: center;
height: 40px;
.search {
width: 200px;
}
}
:deep(.header-row-class) {
th {
background-color: rgba(0,0,0,0.02 ) !important;
//font-weight: 500;
//border-bottom: none;
color: rgba(0, 0, 0, 0.85)
}
}
</style>