背景:现在写后台很多页面的列表长的都比较像,避免代码冗余,现将el-form、el-table、el-pagination封装在一个组件中。这样用起来也比较方便。
上代码
一、主体部分
<style lang="scss">
.TablePageContainer {
.inner_content {
width: 100%;
overflow: hidden;
}
.el-table__fixed,
.el-table__fixed-right {
height: auto !important;
bottom: 17px;
}
}
</style>
<template>
<div class="main__right__inner TablePageContainer" ref="content">
<div class="main__right__content">
<h2 class="list--name">{{ $route.name }}</h2>
<ol v-if="tabshow" class="el-tabs" ref="elTabs">
<span v-for="(item, index) in tabListUsed" :key="index">
<li
:class="{ active: activeName === item.code }"
@click="changeTabs(item.code)"
>
<span>{{ item.text }}</span>
</li>
</span>
</ol>
<!-- 搜索表单 -->
<slot name="form" :activeName="activeName"> </slot>
<!-- 列表 -->
<template title="列表">
<el-table
:data="tableData"
stripe
class="my__table"
ref="Table"
:height="tableHeight"
@selection-change="handleSelectionChange"
@select="handleSelect"
>
<template slot="empty">
<div class="el-empty">
<div class="el-empty__icon"></div>
<div class="el-empty__text">{{ emptyText }}</div>
</div>
</template>
<el-table-column v-if="selection" type="selection" width="55">
</el-table-column>
<!-- 列表数据 -->
<el-table-column
v-for="(item, index) in tableTitleList"
:key="index"
:min-width="item.minWidth"
:prop="item.prop"
:show-overflow-tooltip="item.tipShow"
:label="item.title"
:fixed="item.fixed"
>
<template slot-scope="scope">
<slot name="tableItem" :scope="scope" :item="item"></slot>
</template>
</el-table-column>
<el-table-column
v-if="!hideOptions"
:min-width="optionsWidth"
:show-overflow-tooltip="true"
label="操作"
fixed="right"
>
<template slot-scope="scope">
<div>
<slot name="options" :scope="scope"></slot>
</div>
</template>
</el-table-column>
</el-table>
</template>
<template title="分页">
<slot name="pagination"></slot>
</template>
</div>
</div>
</template>
<script>
export default {
components: {},
props: [
"tableData",
"tableTitleList",
"advancedQueryShow",
"tabList",
"optionsWidth",
"selection",
"queryFormHeight",
"hideOptions",
],
watch: {
advancedQueryShow() {
window.onresize();
},
},
computed: {
// 判断有没有tab页
tabshow() {
return this.tabList && this.tabList.length;
},
//默认tab页
tabListUsed() {
if (this.tabshow) {
// 判断有没有权限限制
if (this.tabList[0].checkRes) {
let arr = this.tabList.filter((item) => {
return item.code !== -1 && this.checkRes(item.checkRes);
});
if (arr && arr.length === this.tabList.length - 1) {
arr.unshift(this.tabList[0]);
}
this.activeName = arr && arr.length ? arr[0].code : "";
return arr;
} else {
this.activeName = this.tabList[0].code;
return this.tabList;
}
} else {
return [];
}
},
},
// 数据源
data() {
//监听窗口尺寸变化改变高级搜索框的宽度
window.onresize = () => {
if (this.advancedQueryShow) {
this.tableHeight =
window.innerHeight -
(this.queryFormHeight ? this.queryFormHeight : 360);
} else {
this.tableHeight =
window.innerHeight -
(this.queryFormHeight ? this.queryFormHeight : 310);
}
};
return {
emptyText: "暂无数据",
//顶部tab标签页选中标记 默认取第一个
activeName: "",
// 列表的高度
tableHeight: "550", //列表高度
};
},
created() {},
// 组件渲染完执行
mounted() {
setTimeout(() => {
window.onresize();
}, 100);
},
// 自定义方法
methods: {
// 列表选中状态变化回调
handleSelectionChange(val) {
this.$emit("selectionChange", val);
},
// 当用户手动勾选数据行的 Checkbox 时触发的事件
handleSelect(selection, row) {
this.$emit("handleSelect", selection, row);
},
// 手动设置列表选中状态 用于跨页面选中列表数据
// data:已选中的数据集合
// identification:列表关联字段标识,用来筛选当前分页里的数据
toggleRowSelection(data, identification) {
if (this.tableData && this.tableData.length && data && data.length) {
this.tableData.forEach((item) => {
data.forEach((_item) => {
if (item[identification] === _item[identification]) {
this.$refs.Table.toggleRowSelection(item, true);
}
});
});
this.$emit("selectOver")
}
},
// 顶部标签页切换
changeTabs(val) {
this.activeName = val;
this.$emit("tabChange", val);
},
},
};
</script>
二、使用
<TablePageContainer
ref="TablePageContainer"
:tableData="tableData"
:tableTitleList="tableTitleList"
:hideOptions="false"
:optionsWidth="200"
:selection="true"
:queryFormHeight="queryFormHeight"
@selectionChange="selectionChange"
@selectOver="selectOver"
>
<template v-slot:form="{}">
<el-row class="search_form_container">
<el-form ref="form" :model="param" label-width="105px">
<div
class="left_form"
:style="`${'padding-right:' + optionWidth + 'px'}`"
>
<!-- 默认搜索项 -->
<el-form-item label="####" class="el-col-8">
<el-input
placeholder="#####"
v-model.trim="param.projectName"
clearable
></el-input>
</el-form-item>
<el-form-item label="#####" class="el-col-8">
<el-select
v-model="param.areaCode"
placeholder="####"
clearable
>
<el-option
v-for="(item, index) in areaCodeList"
border
:label="item.text"
:value="item.code"
:key="index"
></el-option>
</el-select>
</el-form-item>
</div>
<div
class="right_options"
:style="`${'width:' + optionWidth + 'px'}`"
>
<el-form-item class="el-col-24" label-width="0">
<el-button type="primary" plain @click="listSearch"
>查询</el-button
>
<el-button plain @click="reset">重置</el-button>
</el-form-item>
<el-form-item class="el-col-24" label-width="0">
<el-button type="primary" @click="add">新增</el-button>
<el-button type="primary" @click="leadingIn">导入</el-button>
<el-button type="primary" @click="merge">合并</el-button>
</el-form-item>
</div>
</el-form>
</el-row>
</template>
// 循环列 并 可以特殊处理某个列
<template v-slot:tableItem="{ scope, item }">
<div v-if="item.title === '序号'" class="table_td_item_content">
<span>
{{ scope.$index + 1 + (param.page - 1) * param.pageSize }}
</span>
</div>
<div
v-else-if="item.title === '未立项项目名称'"
class="table_td_item_content"
>
<a href="javascript:;" @click="enterDetail(scope.row)" v-if="scope.row.projectName">
{{ scope.row.projectName }}
</a>
</div>
<div
v-else-if="item.title === '项目状态'"
class="table_td_item_content"
>
<span v-if="scope.row.status == 0">已作废</span>
<span v-if="scope.row.status == 1">正常</span>
</div>
<!-- 默认无操作的列 -->
<div class="table_td_item_content" v-else>
{{ scope.row[item.prop] }}
</div>
</template>
// 操作部分
<template v-slot:options="{ scope }">
<div v-if="scope.row.status == 1 && scope.row.relateFlag == 1">
<a href="javascript:;">
<span @click="relieve(scope.row)">解除关联</span>
</a>
</div>
</template>
<template #pagination>
<el-pagination
:total="total"
@size-change="sizeChange"
@current-change="currentChange"
:current-page.sync="param.page"
:page-sizes="[15, 30, 50, 100]"
:page-size="param.pageSize"
layout="total, sizes, prev, pager, next, jumper"
></el-pagination>
</template>
</TablePageContainer>
/* 需要传递参数的注释
* tableData:Array 表格中的数据
* tableTitleList: Array 需要循环的列
* selection:Boolean 是否显示复选框
* hideOptions:Boolean 是否显示操作栏
* optionsWidth:Number 操作栏宽度
* queryFormHeight:Number el-table高度
* selectionChange:function 复选框change事件
*/
// tableTitleList如果过长 建议在外部定义,格式如下
三、引入需要循环的列
export const tableTitleList = [
// { title: "序号", minWidth: 60, tipShow: true, fixed: true },
{
title: "###", // 列名
prop: "###", // 字段名
minWidth: 180, // 列宽
tipShow: true, // 是否显示tooltip
fixed: false // 是否固定列
},
{
title: "###",
prop: "###",
minWidth: 180,
tipShow: true,
fixed: false
},
]
有什么问题欢迎留言 感谢