|
@@ -0,0 +1,159 @@
|
|
|
+<template>
|
|
|
+ <div>
|
|
|
+ <div v-if="isTools" class="text-end mb-3">
|
|
|
+ <v-btn class="ml-2" color="primary" @click="emit('add')">
|
|
|
+ <v-icon left>mdi-plus</v-icon>
|
|
|
+ 新增
|
|
|
+ </v-btn>
|
|
|
+ <slot name="addToTools"></slot>
|
|
|
+ </div>
|
|
|
+ <v-data-table
|
|
|
+ ref="table"
|
|
|
+ :class="`elevation-${elevation} tableColor ${noRadius ? 'noRadius' : ''}`"
|
|
|
+ :headers="headers"
|
|
|
+ :items="items"
|
|
|
+ :item-key="itemKey"
|
|
|
+ :show-select="false"
|
|
|
+ :loading="loading"
|
|
|
+ color="primary"
|
|
|
+ hover
|
|
|
+ hide-default-footer
|
|
|
+ loading-text="Loading... Please wait"
|
|
|
+ fixed-header
|
|
|
+ return-object
|
|
|
+ :disable-sort="disableSort"
|
|
|
+ :items-per-page="itemsPerPage"
|
|
|
+ :no-data-text="noDataText"
|
|
|
+ :hide-default-header="hideDefaultHeader"
|
|
|
+ >
|
|
|
+ <template v-for="name in itemSlot" v-slot:[`item.${name}`]="slotProps">
|
|
|
+ <slot :name="name" v-bind="slotProps"></slot>
|
|
|
+ </template>
|
|
|
+ <template v-for="name in headerSlot" v-slot:[`${name}`]="slotProps">
|
|
|
+ <slot :name="name" v-bind="slotProps"></slot>
|
|
|
+ </template>
|
|
|
+ <template v-if="!Object.keys(slot).includes('actions')" v-slot:[`item.actions`]="{ item }">
|
|
|
+ <td>
|
|
|
+ <v-btn variant="text" color="primary" @click="edit(item)">编辑</v-btn>
|
|
|
+ <v-btn variant="text" color="error" @click="del(item)">删除</v-btn>
|
|
|
+ </td>
|
|
|
+ </template>
|
|
|
+ <template #bottom>
|
|
|
+ <div v-if="showPage && total > 0">
|
|
|
+ <v-divider></v-divider>
|
|
|
+ <CtPagination :total="total" :page="pageInfo.pageNo" :limit="pageInfo.pageSize" @handleChange="handleChangePage"></CtPagination>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </v-data-table>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup>
|
|
|
+defineOptions({ name: 'CtTable'})
|
|
|
+import { ref, computed, useSlots } from 'vue'
|
|
|
+
|
|
|
+const emit = defineEmits(['pageHandleChange', 'del', 'edit', 'add'])
|
|
|
+defineProps({
|
|
|
+ elevation: {
|
|
|
+ type: [Number, String],
|
|
|
+ default: 0
|
|
|
+ },
|
|
|
+ itemKey: {
|
|
|
+ type: String,
|
|
|
+ default: 'id'
|
|
|
+ },
|
|
|
+ disableSort: {
|
|
|
+ type: Boolean,
|
|
|
+ default: true
|
|
|
+ },
|
|
|
+ // 展示列表所有数据
|
|
|
+ itemsPerPage: {
|
|
|
+ type: Number,
|
|
|
+ default: -1
|
|
|
+ },
|
|
|
+ hideDefaultHeader: {
|
|
|
+ type: Boolean,
|
|
|
+ default: false
|
|
|
+ },
|
|
|
+ showPage: {
|
|
|
+ type: Boolean,
|
|
|
+ default: true
|
|
|
+ },
|
|
|
+ loading: {
|
|
|
+ type: Boolean,
|
|
|
+ default: true
|
|
|
+ },
|
|
|
+ headers: {
|
|
|
+ type: Array,
|
|
|
+ default: () => []
|
|
|
+ },
|
|
|
+ items: {
|
|
|
+ type: Array,
|
|
|
+ default: () => []
|
|
|
+ },
|
|
|
+ total: {
|
|
|
+ type: [String, Number],
|
|
|
+ default: 0
|
|
|
+ },
|
|
|
+ pageInfo: {
|
|
|
+ type: Object,
|
|
|
+ default: () => ({
|
|
|
+ size: 10
|
|
|
+ })
|
|
|
+ },
|
|
|
+ isTools: {
|
|
|
+ type: Boolean,
|
|
|
+ default: true
|
|
|
+ },
|
|
|
+ height: {
|
|
|
+ type: [String, Number],
|
|
|
+ default: ''
|
|
|
+ },
|
|
|
+ noRadius: {
|
|
|
+ type: Boolean,
|
|
|
+ default: false
|
|
|
+ },
|
|
|
+ noDataText: {
|
|
|
+ type: String,
|
|
|
+ default: 'No data available'
|
|
|
+ }
|
|
|
+})
|
|
|
+
|
|
|
+const table = ref()
|
|
|
+const slot = useSlots()
|
|
|
+
|
|
|
+const itemSlot = computed(() => {
|
|
|
+ return Object.keys(slot).filter(key => {
|
|
|
+ const data = key.split('.')
|
|
|
+ return data.length === 1
|
|
|
+ })
|
|
|
+})
|
|
|
+
|
|
|
+const headerSlot = computed(() => {
|
|
|
+ return Object.keys(slot).filter(key => {
|
|
|
+ const data = key.split('.')
|
|
|
+ return data.length === 2 && data[0] === 'header'
|
|
|
+ })
|
|
|
+})
|
|
|
+
|
|
|
+const edit = (item) => {
|
|
|
+ emit('edit', item)
|
|
|
+}
|
|
|
+
|
|
|
+const del = (item) => {
|
|
|
+ emit('del', item)
|
|
|
+}
|
|
|
+
|
|
|
+const handleChangePage = (e) => {
|
|
|
+ emit('pageHandleChange', e)
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped lang="scss">
|
|
|
+:deep(.v-table > .v-table__wrapper > table > thead) {
|
|
|
+ background-color: #f7f8fa !important;
|
|
|
+}
|
|
|
+:deep(.v-selection-control__input) {
|
|
|
+ color: var(--v-primary-base) !important;
|
|
|
+}
|
|
|
+</style>
|