Newer
Older
smart-metering-front / src / components / NormalTable / index.vue
<script lang="ts" setup name="NormalTable">
import type { Ref } from 'vue'
import { defineExpose } from 'vue'
import type { TableColumn } from './table_interface'

// ------------------定义props、 emit-------------------
const props = defineProps({
  // 查询条件,此处主要需要分页的条件
  query: {
    type: Object,
    default() {
      return {
        offset: 1,
        limit: 20,
      }
    },
  },
  // loading状态
  loading: {
    type: Boolean,
    default: false,
  },
  // 数据
  data: {
    type: Array,
    default() {
      return []
    },
  },
  // 表格高度
  height: {
    type: Number,
    default() {
      return null
    },
  },
  // 数据总数
  total: {
    type: Number,
    default: 0,
  },
  // 数据列配置
  columns: {
    type: Array<TableColumn>,
    default() {
      return []
    },
  },
  // 是否需要分页控件
  pagination: {
    type: Boolean,
    default: true,
  },
  // 配置项
  options: {
    type: Object,
    default() {
      return {
        needIndex: true, // 是否需要序号列
        border: true, // 是否需要上方边框
      }
    },
  },
  // 可选单页显示条数
  pageSizes: {
    type: Array,
    default() {
      return [10, 20, 30]
    },
  },
  // 表格大小
  size: {
    type: String,
    default: 'default',
  }, // 表格大小,默认,small,mini等,与el-table条件相同
})
const emit = defineEmits(['change', 'selectionChange', 'rowClick'])
// -------定义数据--------------
interface columnsCheckInfo {
  text: string
  show: boolean
}
const columnsChecked: Ref<columnsCheckInfo[]> = ref([])

// 初始化列显示状态
function initColumnsState() {
  columnsChecked.value = []
  for (const column of props.columns) {
    columnsChecked.value.push({ text: column.text, show: !!column.show })
  }
}
defineExpose({
  initColumnsState,
})
// 最终展示列
const columnsFiltered: Ref<TableColumn[]> = ref([])
// 切换列
function changeColumns() {
  columnsFiltered.value = []
  for (const i in props.columns) {
    if (columnsChecked.value[i].show === true) {
      columnsFiltered.value.push(props.columns[i])
    }
  }
}
// 计算索引值方法
function indexMethod(index: number) {
  return props.query.limit * (props.query.offset - 1) + index + 1
}
// 刷新
function refresh() {
  emit('change')
}
// 改变页容量
function handleSizeChange(val: number) {
  emit('change', { size: val })
}
// 改变当前页
function handleCurrentChange(val: number) {
  emit('change', { page: val })
}
// 多选选中结果
function selectionChange(selection: []) {
  emit('selectionChange', selection)
}
// 点击行
function rowClick(row: object, column?: any, event?: any) {
  emit('rowClick', row)
}
// 监听columns
watch(props.columns, (val) => {
  initColumnsState()
  changeColumns()
})

onBeforeMount(() => {
  initColumnsState()
  changeColumns()
})
</script>

<template>
  <div class="normal-table">
    <el-table id="print" ref="table" v-loading="loading" :data="data" height="height" :size="size" :border="false" style="width: 100%;">
      <slot name="preColumns" />
      <el-table-column v-for="column of columns" :key="column.value" :label="column.text" :prop="column.value" :width="column.width" :align="column.align" :show-overflow-tooltip="column.showOverflow ? column.showOverflow : true" />
      <slot name="columns" />
    </el-table>
    <div v-if="props.pagination" style="width: 100%;margin-top: 10px;">
      <el-pagination
        :current-page="props.query.offset"
        :page-sizes="props.pageSizes"
        :page-size="props.query.limit"
        :total="props.total"
        layout="total, sizes, prev, pager, next"
        hide-on-single-page
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
    </div>
  </div>
</template>

<style lang="scss" scoped>
.normal-table {
  width: 100%;
}
</style>