有时遇到这样的需求,就是在表格里面嵌入一个表格,以及要求带有分页,这样在ElementPlus中很好实现。以下使用Vue2语法实现一个简单例子,毕竟Vue3兼容Vue2语法,若想要Vue3版本例子,简单改改就OK了。
(1)/src/views/Example/InlineTable/index.vue
- <template>
- <div class="index" v-loading="elementLoading" element-loading-text="数据正在加载中...">
-
-
- <div class="outer-table-container">
- <el-table
- border
- size="small"
- row-key="id"
- ref="outerTableRef"
- height="100%"
- highlight-current-row
- :data="outerData.list"
- :expand-row-keys="outerData.expandedKeys"
- @expand-change="handleOuterDataExpandChange"
- >
-
- <el-table-column fixed prop="id" label="游戏服务器ID" width="200" align="center">
- <template #default="scope">
- <p>{{ scope.row.id }}p>
- template>
- el-table-column>
-
- <el-table-column fixed prop="id" label="玩家列表" type="expand" width="200" align="center">
- <template #default="scope">
- <div class="outer-table-container-td__playerList" v-loading="scope.row.loading">
-
- <div class="inner-table-container">
- <el-table
- border
- size="small"
- row-key="id"
- height="100%"
- highlight-current-row
- :data="scope.row.list"
- >
-
- <el-table-column fixed prop="id" label="玩家ID" width="200" align="center">
- <template #default="scope">
- <p>{{ scope.row.id }}p>
- template>
- el-table-column>
-
- <el-table-column prop="power" label="玩家战力" width="auto" align="center" show-overflow-tooltip>
- <template #default="scope">
- <p style="text-align: left; text-indent: 10px; margin: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;">{{ scope.row.power }}p>
- template>
- el-table-column>
-
- <el-table-column fixed="right" label="操作" align="center" width="150">
- <template #default="scope">
- <div class="inner-table-container-td__operation">
- <el-row>
- <el-col :span="24">
-
- <el-tooltip effect="dark" content="查看详情" placement="top" :enterable="false" :hide-after="0">
- <el-button size="small" type="" style="border: unset" plain circle @click="
- () => {
- log('查看详情 =>', scope.row)
- }
- ">
- <el-icon :size="16"><View />el-icon>
- el-button>
- el-tooltip>
-
- el-col>
- el-row>
- div>
- template>
- el-table-column>
- el-table>
- div>
-
-
-
- <div class="inner-pagger-container">
- <el-pagination
- v-if="scope.row.total > 0"
- small
- background
- v-model:current-page="scope.row.pageNumber"
- v-model:page-size="scope.row.pageSize"
- :total="scope.row.total"
- :page-sizes="[10, 20, 50, 100]"
- layout="total, sizes, prev, pager, next, jumper"
- @size-change="handleInnerTableSizeChange(scope.row)"
- @current-change="handleInnerTableCurrentChange(scope.row)"
- />
- div>
-
- div>
- template>
- el-table-column>
-
- <el-table-column prop="host" label="游戏服务器名称" width="auto" min-width="400" align="center" show-overflow-tooltip>
- <template #default="scope">
- <p class="outer-table-container-td__name">{{ scope.row.host }}p>
- template>
- el-table-column>
-
- <el-table-column label="创建时间" width="400" align="center">
- <template #default="scope">
- <div>{{ scope.row.createTime ? scope.row.createTime : '-' }}div>
- template>
- el-table-column>
- el-table>
- div>
-
-
-
- <div class="outer-pagger-container">
- <el-pagination
- small
- background
- :current-page="outerData.pageNumber"
- :page-size="outerData.pageSize"
- :page-sizes="[20, 30, 50, 100]"
- :total="outerData.total"
- layout="total, sizes, prev, pager, next, jumper"
- @size-change="handleOuterTableSizeChange"
- @current-change="handleOuterTableCurrentChange"
- >
- el-pagination>
- div>
-
-
- div>
- template>
-
- <script>
- export default {
- data: () => ({
-
- // 加载标志
- elementLoading: true,
-
- // 外层数据
- outerData: {
- list: [], // 列表
- selectedList: [], // 已选列表
- expandedKeys: [], // 已展开键集合
- expandedList: [], // 已展开列表
- total: 521, // 总数
- pageNumber: 1, // 当前页
- pageSize: 20, // 页码大小
- },
-
- // 打印日志
- log: console.log
- }),
- created() {
- this.init()
- },
- mounted() {
- },
- methods: {
- // ---- ---- ---- ---- ^ 事件调用方法 ---- ---- ---- ----
-
- /**
- * 初始化外层表格
- */
- init() {
- const list = []
- for (let i = 0; i < this.outerData.pageSize; i++) {
- const number = parseInt(Math.random() * 10000) + i
- const row = {
- id: number,
- host: `游戏服务器 - ${number}`,
- createTime: new Date()
- }
- list.push(row)
- }
- this.outerData.list = list
- this.outerData.total = this.outerData.total
- this.elementLoading = false
- },
-
- /**
- * 外层表格 - 页码改变方法
- */
- handleOuterTableSizeChange(val) {
- this.elementLoading = true
- this.outerData.pageNumber = 1
- this.outerData.pageSize = val
- const frontRecords = this.outerData.pageSize * (this.outerData.pageNumber - 1)
- const remainRecords = this.outerData.total - frontRecords
-
- let list = []
- if (remainRecords >= this.outerData.pageSize) {
- for (let i = 0; i < this.outerData.pageSize; i++) {
- const number = parseInt(Math.random() * 10000) + i
- const row = {
- id: number,
- host: `游戏服务器 - ${number}`,
- createTime: new Date()
- }
- list.push(row)
- }
- } else {
- for (let i = 0; i < remainRecords; i++) {
- const number = parseInt(Math.random() * 10000) + i
- const row = {
- id: number,
- host: `游戏服务器 - ${number}`,
- createTime: new Date()
- }
- list.push(row)
- }
- }
-
- setTimeout(() => {
- this.outerData.list = list
- this.outerData.total = this.outerData.total
- this.elementLoading = false
- }, 200)
- },
-
- /**
- * 外层表格 - 当前页改变方法
- */
- handleOuterTableCurrentChange(val) {
- this.elementLoading = true
- this.outerData.pageNumber = val
- const frontRecords = this.outerData.pageSize * (this.outerData.pageNumber - 1)
- const remainRecords = this.outerData.total - frontRecords
-
- let list = []
- if (remainRecords >= this.outerData.pageSize) {
- for (let i = 0; i < this.outerData.pageSize; i++) {
- const number = parseInt(Math.random() * 10000) + i
- const row = {
- id: number,
- host: `游戏服务器 - ${number}`,
- createTime: new Date()
- }
- list.push(row)
- }
- } else {
- for (let i = 0; i < remainRecords; i++) {
- const number = parseInt(Math.random() * 10000) + i
- const row = {
- id: number,
- host: `游戏服务器 - ${number}`,
- createTime: new Date()
- }
- list.push(row)
- }
- }
-
- setTimeout(() => {
- this.outerData.list = list
- this.outerData.total = this.outerData.total
- this.elementLoading = false
- }, 200)
- },
-
- /**
- * 外层表格 - 展开/收起某一行事件句柄方法
- */
- async handleOuterDataExpandChange(row, expandedRows) {
- this.outerData.expandedList = expandedRows
- const index = this.outerData.expandedList.findIndex((item) => item.id === row.id)
- if (index != -1) {
- // 展开
- this.getPlayerList(row)
- } else {
- // 收起
- row.loading = true
- }
- },
-
- /**
- * 根据游戏服务器获取玩家列表
- */
- async getPlayerList(row) {
- for (let vo of this.outerData.list) {
- // 匹配游戏服务器
- if (vo.id == row.id) {
- vo.loading = false
- vo.list = [] // 列表
- vo.total = 25 // 总数
- vo.pageNumber = 1 // 当前页
- vo.pageSize = 10 // 页码大小
- const list = []
- for (let i = 0; i < vo.pageSize; i++) {
- const number = parseInt(Math.random() * 100000000) + i
- const row = {
- id: number,
- power: Math.pow(number, 5),
- }
- list.push(row)
- }
- vo.list = list
- }
- }
- },
-
- /**
- * 内嵌表格 - 页码改变方法
- */
- handleInnerTableSizeChange(row) {
- row.loading = true
- row.pageNumber = 1
- const frontRecords = row.pageSize * (row.pageNumber - 1)
- const remainRecords = row.total - frontRecords
-
- let list = []
- if (remainRecords >= row.pageSize) {
- for (let i = 0; i < row.pageSize; i++) {
- const number = parseInt(Math.random() * 100000000) + i
- const row = {
- id: number,
- power: Math.pow(number, 5),
- }
- list.push(row)
- }
- } else {
- for (let i = 0; i < remainRecords; i++) {
- const number = parseInt(Math.random() * 100000000) + i
- const row = {
- id: number,
- power: Math.pow(number, 5),
- }
- list.push(row)
- }
- }
-
- setTimeout(() => {
- row.list = list
- row.total = row.total
- row.loading = false
- }, 200)
- },
-
- /**
- * 内嵌表格 - 当前页改变方法
- */
- handleInnerTableCurrentChange(row) {
- row.loading = true
- const frontRecords = row.pageSize * (row.pageNumber - 1)
- const remainRecords = row.total - frontRecords
-
- let list = []
- if (remainRecords >= row.pageSize) {
- for (let i = 0; i < row.pageSize; i++) {
- const number = parseInt(Math.random() * 100000000) + i
- const row = {
- id: number,
- power: Math.pow(number, 5),
- }
- list.push(row)
- }
- } else {
- for (let i = 0; i < remainRecords; i++) {
- const number = parseInt(Math.random() * 100000000) + i
- const row = {
- id: number,
- power: Math.pow(number, 5),
- }
- list.push(row)
- }
- }
-
- setTimeout(() => {
- row.list = list
- row.total = row.total
- row.loading = false
- }, 200)
- },
- }
- }
- script>
-
- <style lang="less" scoped>
- .index {
- display: flex;
- flex-direction: column;
- width: 100%;
- height: 100%;
- overflow: hidden;
-
- // ---- ---- ---- ---- ^ 外层表格 样式 ---- ---- ---- ----
- :deep(.outer-table-container) {
- flex: 1;
- position: relative;
- overflow: hidden;
-
- .el-table {
-
- th {
-
- .cell {
- color: #000;
- font-weight: normal;
- font-size: 13px;
- }
- }
-
- td {
- padding: 2.5px 0;
-
- .cell {
- // color: #000;
- font-size: 13px;
- padding: 0;
- }
- }
-
-
- .outer-table-container-td__playerList {
- height: auto;
- overflow: auto;
- padding: 4px 7px;
-
- /* ^ 内嵌表格 */
- .inner-table-container {
- position: relative;
- overflow: hidden;
-
- .el-table {
-
- th {
-
- .cell {
- color: #000;
- font-weight: normal;
- font-size: 13px;
- }
- }
-
- td {
- padding: 2.5px 0;
-
- .cell {
- // color: #000;
- font-size: 13px;
- padding: 0;
- }
- }
-
- .el-table__cell {
- // background-color: #f8f8f8;
- }
- }
-
- /* 操作 */
- .inner-table-container-td__operation {
-
- .el-button {
- position: relative;
- margin: 0px 1px;
- }
- }
- /* / 操作 */
- }
- /* / 内嵌表格 */
-
- /* ^ 内嵌分页 */
- .inner-pagger-container {
- position: relative;
- width: 100%;
- height: 26px;
- margin-top: 7px;
-
- .el-pagination {
- position: absolute;
- top: 0;
- // left: 0;
- right: 0;
- bottom: 0;
- margin: 0 auto;
- width: fit-content;
-
- .btn-prev, .btn-next, .el-pager li {
- border: 1px solid #dcdfe6;
- }
-
- .el-pager li.is-active {
- border-color: #5e7ce0;
- }
- }
- }
- /* / 内嵌分页 */
- }
-
- /* 操作 */
- .operation {
-
- .el-button {
- position: relative;
- margin: 0px 1px;
- }
- }
- /* / 操作 */
- }
- }
- // ---- ---- ---- ---- / 外层表格 样式 ---- ---- ---- ----
-
- // ---- ---- ---- ---- ^ 外层分页 样式 ---- ---- ---- ----
- :deep(.outer-pagger-container) {
- padding: 7px 0;
- width: 100%;
- height: 26px;
- position: relative;
-
- .el-pagination {
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- margin: 0 auto;
- width: fit-content;
-
- .btn-prev, .btn-next, .el-pager li {
- border: 1px solid #dcdfe6;
- }
-
- .el-pager li.is-active {
- border-color: #5e7ce0;
- }
- }
- }
- // ---- ---- ---- ---- / 外层分页 样式 ---- ---- ---- ----
- }
- style>