el-table二次封装


<template>
<div style="margin: 20px 20px 100px 20px">
<el-table
border
class="customer-no-border-table"
element-loading-text="数据正在加载中..."
:row-class-name="tableRowClassName"
:header-cell-style="{ background: '#E7F2FD', color: '#252525' }"
style="width: 100%; border-top: 1px solid #409eff"
v-loading="loading"
:ref="tableName"
:data="tableData"
:highlight-current-row="light"
@row-click="getrow"
@sort-change="sortChange"
@selection-change="handleSelectionChange"
:row-key="rowKey"
:reserve-selection="reserve"
:max-height="fixedHeight > 0 ? fixedHeight : tableHeight - difference"
>
<!-- 复选框 -->
<el-table-column
type="selection"
v-if="choice"
width="50"
:align="headerAlign"
:key="Math.random()"
>
</el-table-column>
<!-- 序号 -->
<el-table-column
label="序号"
v-if="serialNumber"
width="50"
type="index"
:align="headerAlign"
:key="Math.random()"
>
</el-table-column>
<!-- 动态表头 -->
<!-- {
prop:'title',// 列表渲染的字段key
label:'菜单名称',// 字段中文名称
align:''// 列表内容文字的位置
sort:true, // 是否排序
form:'string', (可选:string/img/Button/filter/select)
key:{label: "label",value: "value"} // 这个配置是下拉框的form = select
filter(row){},// 对数据进行过滤 并返回内容 和vue 过滤器一样的功能
configure:{ // 配置按钮的参数对象
type:''// 参考el-button 官网参数
size:''// 参考el-button 官网参数
},
callback(row){} //点击按钮的回调函数
} -->
<div v-for="(item, index) in tableLabel" :key="index">
<!-- 普通数据展示/或者字符串文本展示 -->
<el-table-column
v-if="!item.form || item.form === 'string'"
:prop="item.prop"
:width="item.width"
:label="item.label"
:sortable="item.sort"
:align="item.align ? item.align : 'center'"
:key="index"
show-overflow-tooltip
>
</el-table-column>
<!-- 数据过滤:根据filter函数自定义规则进行数据返回 -->
<el-table-column
v-else-if="item.form === 'filter'"
:width="item.width"
:label="item.label"
:sortable="item.sort"
:align="item.align ? item.align : 'center'"
:key="index"
show-overflow-tooltip
>
<template slot-scope="scope">
{{ item.filter(scope.row) }}
</template>
</el-table-column>
<!-- 图片展示 -->
<el-table-column
v-else-if="item.form === 'img'"
:width="item.width"
:label="item.label"
:sortable="item.sort"
:align="item.align ? item.align : 'center'"
:key="index"
>
<template slot-scope="scope">
<!-- 如果是字符串就是一个图片 -->
<div v-if="typeof scope.row[item.prop] === 'string'">
<el-image
style="width: 22px; height: 22px"
:src="scope.row[item.prop] ? scope.row[item.prop] : defaultImg"
:preview-src-list="[
scope.row[item.prop] ? scope.row[item.prop] : defaultImg,
]"
>
</el-image>
</div>
<!-- 不是字符串就统一数组来处理 -->
<div
v-else-if="
scope.row[item.prop] !== null && scope.row[item.prop].length > 0
"
>
<span
v-for="(item1, index1) in scope.row[item.prop]"
:key="index1"
>
<el-image
style="width: 22px; height: 22px; margin-right: 20px"
:src="scope.row[item.prop][index1]"
:preview-src-list="scope.row[item.prop]"
:z-index="2100"
>
</el-image>
</span>
</div>
</template>
</el-table-column>
<!-- 按钮展示 -->
<el-table-column
v-else-if="item.form === 'Button'"
:width="item.width"
:label="item.label"
:sortable="item.sort"
:align="item.align ? item.align : 'center'"
:key="index"
>
<template slot-scope="scope">
<el-button
@click="item.callback && item.callback(scope.row)"
:type="
item.configure && item.configure.type ? item.configure.type : ''
"
:size="
item.configure && item.configure.size ? item.configure.size : ''
"
>
{{ item.configure.text || "缺少按钮文字" }}</el-button
>
</template>
</el-table-column>
<!-- 多个复选框 -->
<el-table-column
v-else-if="item.form === 'checkbox'"
:width="item.width"
:label="item.label"
:sortable="item.sort"
:align="item.align ? item.align : 'center'"
:key="index"
>
<template slot-scope="scope">
<span
style="margin-left: 5px"
v-for="(v, i) in scope.row.authority"
:key="i"
>
<el-checkbox
:label="v.name"
name="type"
v-model="v.open"
></el-checkbox>
</span>
<span v-if="scope.row.authority && scope.row.authority.length < 1"
>暂无</span
>
</template>
</el-table-column>
<!-- 单选框 -->
<!-- 表头配置tableLabel -->
<!-- {
prop: 'timeType',最终下拉框每次选中的值都绑定到 这个定义的字段上
label: '时间单位',
align: 'center',
form: "radio",
key: {
label: "label",
value: "value"
},
width: 250,
}, -->
<!-- 列表循环数据 每一项必须要有 radioList属性为数组 -->
<el-table-column
v-else-if="item.form === 'radio'"
:width="item.width"
:label="item.label"
:sortable="item.sort"
:align="item.align ? item.align : 'center'"
:key="index"
>
<template slot-scope="scope">
<div v-if="scope.row.radioList && scope.row.radioList.length">
<el-radio-group v-model="scope.row[item.prop]">
<el-radio
v-for="items in scope.row.radioList"
:key="items[item.key.value]"
:label="items[item.key.value]"
>{{ items[item.key.label] }}</el-radio
>
</el-radio-group>
</div>
<div v-else>
<span style="color: #e6a23c">缺少radioList属性数组!</span>
</div>
</template>
</el-table-column>
<!-- 下拉框 -->
<!-- 表头配置tableLabel -->
<!-- {
prop:'xxx' 最终下拉框每次选中的值都绑定到 这个定义的字段上
form:'select',
key:{label: "label",value: "value"}
} -->
<!-- 列表循环数据 每一项必须要有 options属性为数组 -->
<el-table-column
v-else-if="item.form === 'select'"
:width="item.width"
:label="item.label"
:sortable="item.sort"
:align="item.align ? item.align : 'left'"
:key="index"
>
<template slot-scope="scope">
<el-select
v-model="scope.row[item.prop]"
placeholder="请选择"
size="mini"
>
<el-option
v-for="items in scope.row.options"
:key="items[item.key.value]"
:label="items[item.key.label]"
:value="items[item.key.value]"
>
</el-option>
</el-select>
</template>
</el-table-column>
<!-- 输入框 -->
<el-table-column
v-else-if="item.form === 'input'"
:width="item.width"
:label="item.label"
:sortable="item.sort"
:align="item.align ? item.align : 'left'"
:key="index"
>
<template slot-scope="scope">
<el-input
placeholder="请输入内容"
v-model="scope.row[item.prop]"
size="mini"
>
</el-input>
</template>
</el-table-column>
<!-- 自定义 -->
<el-table-column
v-else-if="item.form === 'my'"
:width="item.width"
:label="item.label"
:sortable="item.sort"
:align="item.align ? item.align : 'center'"
:key="index"
show-overflow-tooltip
>
<template slot-scope="scope">
<span
style="text-decoration: underline; color: blue"
@click="item.callback(Object.assign({}, scope.row))"
>{{ item.filter(scope.row) }}</span
>
</template>
</el-table-column>
<!-- 固定列 -->
<el-table-column
v-else-if="item.form === 'fixed'"
:width="item.width"
:label="item.label"
:sortable="item.sort"
:align="item.align ? item.align : 'center'"
:key="index"
>
</el-table-column>
</div>
<el-table-column
label="操作"
:width="operation.width"
v-if="JSON.stringify(operation) !== '{}'"
>
<template slot-scope="scope">
<!-- 操作按钮 -->
<!-- {
label:'删除',
type:'danger',// 按钮类型  参考el-button 官网参数
size:"mini", // 按钮大小  参考el-button 官网参数
plain:true, // 是否朴素按钮
callback(row){}, // 点击按钮回调函数
disabled(row){ return true/false} //是否禁用 可以条件判断 让函数返回布尔值
authority:true// 如果涉及到权限按钮控制的 就添加这个属性(false普通按钮/true权限按钮)
authorityEvent(row){return true/false}
} -->
<!-- 动态操作按钮 -->
<div class="flex center">
<div
class="flex center"
v-for="(item, index) in operation.Button"
:key="index"
>
<el-button
style="margin: 0 5px"
v-if="!item.authority"
@click="item.callback(Object.assign({}, scope.row))"
:type="item.type ? item.type : ''"
:size="item.size ? item.size : ''"
:disabled="item.disabled && item.disabled(scope.row)"
:plain="plain"
>{{ item.label }}</el-button
>
<el-button
style="margin: 0 5px"
v-else-if="
item.authority &&
item.authorityEvent &&
item.authorityEvent(item.label)
"
@click="item.callback(Object.assign({}, scope.row))"
:type="item.type ? item.type : ''"
:size="item.size ? item.size : ''"
:disabled="item.disabled && item.disabled(scope.row)"
:plain="plain"
>{{ item.label }}</el-button
>
</div>
</div>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<div
style="padding: 10px"
v-if="paging"
:style="{ 'text-align': pagingPosition }"
>
<el-pagination
@size-change="handleNumberChange"
@current-change="handleCurrentPage"
:current-page="searchData.page"
:page-sizes="[10, 15, 20, 30, 40, 50]"
:page-size="searchData.limit"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
>
</el-pagination>
</div>
</div>
</template>
<!-- /**
* 组件说明
* 属性:
* 参数                     说明                           类型                    默认值
* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
* tableData              列表 的数据源                   Array                      []
* treeProps              支持树类型的数据的列表显示       Object                     {children: 'children'}
* rowKey                 树类型的数据 列表必须要指定        String                     '_id'
* serialNumber           是否需要序号                     Boolean                    true
* headerAlign               表头对齐方式/复选框/序号              String                    'left'/'center'/'right'
* tableLabel               动态表头渲染数组                Array                     []
* choice                   是否开启多选复选框                Boolean                 false
* operation               操作列表按钮                    Object                     {}
* total                   分页总页数                     number                     0
* paging                   是否开启分页                     Boolean                 false
* pagingPosition           分页底部的位置                     String                     'left'/'center'/'right'
* fixedHeight               固定table列表高度                 number                      0
* pagingPage               分页参数                         Object                     {pageSize: 20,page: 1}
* headButton             列表头部按钮是否显示              Boolean                   false
* 回调事件:
* select  获取复选框选中对象 返回数组
* sortChange     获取当前点击表头指定排序结果
* handleCurrentPage     每次切换页数触发并且回调页数
* handleNumberChange     每次切换展示的条数触发并且回调
*/ -->
<script>
const defaultImg = require("../assets/nodata.png");
export default {
props: {
// ref的名字
tableName: {
type: String,
default: "",
},
// 是否记忆分页选中行
reserve: {
type: Boolean,
default: false,
},
// 是否高亮当前行
ligth: {
type: Boolean,
default: false,
},
// 是否朴素按钮
plain: {
type: Boolean,
default: true,
},
// 数据
tableData: {
type: Array,
default: () => [],
},
// 支持树类型的数据的显示
treeProps: {
type: Object,
default: () => ({
children: "children",
}),
},
//树类型的数据 列表必须要指定row-key id
rowKey: {
type: String,
default: "_id",
},
// 是否需要序号
serialNumber: {
type: Boolean,
default: true,
},
// 表头对齐方式
headerAlign: {
type: String,
default: "center",
},
// 表头
tableLabel: {
type: Array,
default: () => [],
},
// 复选框
choice: {
type: Boolean,
default: false,
},
// 操作按钮参数
operation: {
type: Object,
default: () => ({}),
},
// 总条数
total: {
type: Number,
default: 0,
},
//分页
paging: {
type: Boolean,
default: false,
},
// 分页组件位置
pagingPosition: {
type: String,
default: "left",
},
// 固定高度
fixedHeight: {
type: Number,
default: 0,
},
// 分页组件参数
pagingPage: {
type: Object,
default: () => ({
limit: 10,
page: 1,
}),
},
// 设置偏移高度(到达每个页面不同内容高度,都可以让列表高度填充满整个可视区)
difference: {
type: Number,
default: 0,
},
},
data() {
return {
defaultImg: defaultImg,
tableHeight: document.documentElement.clientHeight - (70 + 80), // 表格自适应高度 默认撑满
// 分页固定参数
searchData: {
limit: this.pagingPage.limit,
page: this.pagingPage.page,
},
};
},
methods: {
tableRowClassName({ rowIndex }) {
if (rowIndex % 2 === 1) {
return "success-row";
}
return "";
},
// 重置分页参数
pagingReset(limit, page) {
if (!limit && !page) {
this.searchData.limit = 10;
this.searchData.page = 1;
} else if (limit) {
this.searchData.limit = limit;
} else {
this.searchData.page = page;
}
},
// 切换页数
handleCurrentPage(val) {
this.searchData.page = val;
this.$emit("handleCurrentPage", val);
},
// 每页N展示条
handleNumberChange(val) {
this.searchData.limit = val;
this.$emit("handleNumberChange", val);
},
//选中当前行
getrow(row) {
this.$emit("getrow", row);
},
// 复选框勾选
handleSelectionChange(array) {
console.log(array, "array");
this.$emit("handleSelectionChange", array);
},
// 排序
sortChange(column, prop, order) {
console.log(column, "column");
console.log(prop, "prop");
console.log(order, "order");
this.$emit("sortChange", column);
}
},
};
</script>
<style scoped lang='less'>
/* 默认el-table 行高过于高,这里设置减少padding之间的间距 */
/deep/ th {
padding: 9px 0;
}
/deep/ .el-table td {
padding: 9px 0;
}
</style>

  

<template>
<div>
<table-List
:tableData="tableData"
:tableLabel="tableLabel"
:choice="choice"
:light="light"
:reserve="reserve"
:paging="paging"
:operation="operation"
:total="total"
pagingPosition="center"
headerAlign="center"
@sortChange="sortChange"
@getrow="getrow"
@handleSelectionChange="handleSelectionChange"
@handleNumberChange="handleNumberChange"
@handleCurrentPage="handleCurrentPage"
>
</table-List>
</div>
</template>
<script>
import tableList from "./table.vue";
export default {
components: {
tableList,
},
data() {
return {
light: true, //高亮当前行
paging: true, //是否分页
pagingPage: {
limit: 10,
page: 1,
},
tableData: [
{ nickName: "111", friendCount: 123 },
{ nickName: "222", friendCount: 456 },
], //数据源
tableLabel: [
{
prop: "nickName",
label: "用户昵称",
align: "center",
form: "filter",
filter(row) {
if ((row.nickName = "111")) {
return `丫丫`;
} else {
return "哈哈";
}
},
},
{
prop: "friendCount",
label: "好友数量",
align: "center",
form: "my",
filter(row) {
if (row.friendCount == "123") {
return `百度`;
} else {
return "billbill";
}
},
callback: (row) => {
if (row.friendCount == "123") {
window.open("https://www.baidu.com/?tn=02003390_19_hao_pg");
} else {
window.open("https://blog.csdn.net/jlsdzhj/article/details/80647682");
}
},
},
],
operation: {
width: "220",
Button: [
{
label: "查看",
size: "mini",
authority: false,
callback(k) {
console.log(k);
},
},
],
},
total: 0,
};
},
methods: {
// 分页
handleNumberChange(val) {
console.log(val, "当前页码");
},
// 每一页展示多少条切换
handleCurrentPage(val) {
console.log(val, "当前展示条数");
},
// 排序
sortChange(column) {
console.log(column, "column");
},
//多选
handleSelectionChange(array) {
console.log(array, "array");
this.selectList = array;
},
// 单选
getrow(row) {
console.log(row, "选中行");
this.trData = row;
},
},
};
</script>
<style lang="scss" scoped>
</style>
components:{tableList,
},
data(){
return{
tableData: [
{nickName:"111",friendCount:123,},{nickName:"222",friendCount:456},{}],//数据源
tableLabel:[
{
prop: 'nickName',
label: '用户昵称',
align: 'center',
form:'filter',
filter(row){
if(row.nickName='111'){
return '丫丫'
}else{
return '哈哈'
}
}
},
{
prop: 'friendCount',
label: '好友数量',
align: 'center',
},
],
operation:{
width: '220',
Button:[
{
label: '查看',
size: "mini",
authority: false,
callback(k) {
console.log(k)
}
}
]
},
total:10,
}
} ,
methods:{
handleNumberChange(val){},// 每一页展示多少条切换
handleCurrentPage(val){},//切换分页
sortChange(column){},// 排序
select(valArr){},//列表复选框
}             

  

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/287972.html

(0)
上一篇 2022年9月6日
下一篇 2022年9月6日

相关推荐

发表回复

登录后才能评论