vue3 中如何优雅的使用 el-table
我正在参加「掘金·启航计划」
优点
摆脱繁琐的 繁琐的分页操作表格操作等,以及反复的重复 dom。
想法
将 el-table 封装成一个全局组件. 一切皆可配置.
- api 可配置
- el-table-column
- 分页配置
- 一屏展示内容
用法
const columns = reactive([
{
label: "name",
prop: "name"
},
{
slot: true,
slotName: "age"
},
{
slot: true,
slotName: "handle"
}
])
const getTableData = ()=>{
//同样你可以返回的是api
return Promise.resolve(()=>{
return{
data:[{name:"yoge",age:"18"}]
total:1
}
})
}
const table = ref()
table.load()
<Gtable :fetch="getTableData" ref="table" :columns="columns">
<template v-slot:header>
<el-card v-loading="loading" shadow="never" class="search-wrapper">
<el-form ref="searchFormRef" :inline="true" :model="searchData">
<el-form-item prop="username" label="简历模板名称">
<el-input v-model="searchData.name" placeholder="请输入" />
</el-form-item>
<el-form-item>
<el-button type="primary" :icon="Search" @click="handleSearch">查询</el-button>
<el-button :icon="Refresh" @click="resetSearch">重置</el-button>
</el-form-item>
</el-form>
</el-card>
</template>
<template v-slot:btns>
<el-button type="primary" :icon="CirclePlus" @click="addNoteTemCate">添加简历模板分类</el-button>
<el-button type="primary" :icon="CirclePlus" @click="addNoteTem">添加简历模板</el-button>
</template>
<template v-slot:age>
<el-table-column prop="roles" label="age" align="center">
<template #default="{ row }"> {{row.age}} </template>
</el-table-column>
</template>
<template v-slot:handle>
<el-table-column fixed="right" label="操作" width="150" align="center">
<template #default="scope">
<el-button type="primary" text bg size="small" @click="handleUpdate(scope.row)">修改</el-button>
<el-button type="danger" text bg size="small" @click="handleDelete(scope.row)">删除</el-button>
</template>
</el-table-column>
</template>
</Gtable>
效果图
表格封装
<template>
<div class="app-container">
<slot name="header" />
<div class="mb-5">
<slot name="btns" />
</div>
<el-table :height="height" :data="tableList.data" border v-loading="loading" ref="table">
<template v-for="(item, i) in props.columns">
<slot v-if="item.slot" :name="item.slotName" />
<el-table-column v-if="!item.slot" v-bind="item" :key="i" />
</template>
</el-table>
<el-pagination
class="mt-2 float-right"
background
:layout="props.layout"
:page-sizes="props.pageSizes"
:total="total"
:page-size="pageSize"
:currentPage="currentPage"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
</template>
<script setup lang="ts">
import { reactive, ref, Ref, onMounted } from "vue"
import type { TableInstance } from "element-plus"
import type { columnsType } from "./types/index"
const props = defineProps({
columns: {
type: Array as () => columnsType[],
default: () => []
},
fetch: {
type: Function,
required: true
},
layout: {
type: String,
default: " total, prev, pager, next"
},
pageSizes: {
type: Array as () => number[],
default: () => [10, 20, 50, 100]
},
pageSize: {
type: Number,
default: 10
},
currentPage: {
type: Number,
default: 1
}
})
const tableList = reactive({ data: [] })
const table: Ref<TableInstance | null> = ref(null)
const total = ref(0)
const height = ref(0)
const currentPage = ref(1)
const pageSize = ref(10)
const loading = ref(false)
const handleSizeChange = () => {}
const handleCurrentChange = () => {}
const load = async () => {
loading.value = true
const data = await props.fetch(params)
tableList.data = data.data
total.value = data.total
loading.value = false
}
onMounted(() => {
updataHeight()
window.addEventListener("resize", updataHeight)
})
const updataHeight = () => {
nextTick(() => {
const $el = table.value && table.value.$el
let h = 0
const indexs = [0, 1, 3]
indexs.forEach((index) => {
h += $el.parentNode.children[index].offsetHeight
})
height.value = $el.parentNode?.offsetHeight - h - 65
console.log(height.value, "height")
})
}
defineExpose({ load, updataHeight })
</script>
<style lang="scss" scoped>
.app-container {
height: calc(100vh - 90px);
overflow: scroll;
}
</style>
- fetch 外部定义获取列表函数
- load 获取表格函数
附上代码
Ending
❀ 完结撒花 ❀ 都看到这了 点个赞吧~