ps: 1.3版本
案例:
完整代码:
可直接复制粘贴,但一定要全看完!
v-slot="scopeRows" 是vue3的写法;
vue2是 slot-scope="scope"
<template>
<!-- 简单表格、多层表头、页码、没有合并列行 -->
<div class="maintenPublictable">
<!--cell-style 改变某一列行的背景色 -->
<!-- tree-props 配置树形子表
row-click: 单击事件
highlight-current-row:高亮选中某行
default-expand-all:默认是否展开字列表
current-change:管理选中时触发的事件
selection-change:多选框
row-key="id": id:一定要跟后台返回来的id一致,不一致,会出错
-->
<!-- :tree-props="{ children: 'children', hasChildren: 'hasChildren' }" -->
<el-table
ref="table"
:data="tableData"
:height="getHeight"
border
highlight-current-row
@selection-change="handleSelectionChange"
:key="itemKey"
:cell-style="tableCellStyle"
@row-click="clickRow"
row-key="ID"
:default-expand-all="defaultall"
:highlight-current-row="highlightCurrent"
@current-change="handleCurrentChangeRow"
:tree-props="{ children: 'Children', }"
>
<el-table-column
type="index"
width="55"
label="序号"
>
</el-table-column>
<el-table-column
type="selection"
v-if="isSelection"
width="55"
>
</el-table-column>
<!-- item.direction 方向,判断居中还是靠右 -->
<template v-for="(item, index) in tableHeader">
<!-- 1. 这是第一层 -->
<!-- sortable: 排序 -->
<el-table-column
v-if="!item.Children"
:key="index"
:prop="item.prop"
:label="item.label"
header-align="center"
:align="item.direction"
:min-width="item.width"
:sortable="item.sortable"
>
<!--需封装动态展示并且适合多种输入 todo -->
<template
v-slot="scopeRows"
v-if="item.label === '在库数量'"
>
<el-input
v-model="scopeRows.row.editRow.InStockQuantity"
type="number"
oninput="if(value<0)value=0"
@blur="getRowData(scopeRows.row.editRow)"
></el-input>
</template>
<template
v-slot="scopeRows"
v-if="item.label === '在库金额'"
>
<el-input
v-model="scopeRows.row.editRow.InStockAmount"
type="number"
@blur="getRowData(scopeRows.row.editRow)"
oninput="if(value<0)value=0"
></el-input>
</template>
<template
v-slot="scopeRows"
v-if="item.label === '库位'"
>
<el-select
v-model=" scopeRows.row.editRow.StoreLocationID"
@change="getRowData(scopeRows.row.editRow)"
>
<el-option
v-for="item in StorageLocation"
:key="item.ID"
:label="item.LocationName"
:value="item.ID"
>
</el-option>
</el-select>
</template>
<template
v-slot="scopeRows"
v-if="item.label === '风力发电有限公司1'"
>
<el-input
v-model="scopeRows.row.Amount.Amount1"
type="number"
@blur="getRowData(scopeRows.row.Amount)"
:disabled=" (rowID!=scopeRows.row.SubjectsID && !this.disableD) || (rowID==scopeRows.row.SubjectsID && this.disableD) "
oninput="value=value.replace(/^0|[^0-9]/g, '')"
></el-input>
</template>
<template
v-slot="scopeRows"
v-if="item.label === '溪木源公司2'"
>
<el-input
v-model="scopeRows.row.Amount.Amount2"
type="number"
@blur="getRowData(scopeRows.row.Amount)"
:disabled="rowID!=scopeRows.row.SubjectsID "
oninput="value=value.replace(/^0|[^0-9]/g, '')"
></el-input>
</template>
<template
v-slot="scopeRows"
v-if="item.label === '大风车有限公司3'"
>
<el-input
v-model="scopeRows.row.Amount.Amount3"
type="number"
@blur="getRowData(scopeRows.row.Amount)"
:disabled="rowID!=scopeRows.row.SubjectsID "
oninput="value=value.replace(/^0|[^0-9]/g, '')"
></el-input>
</template>
<template
v-slot="scopeRows"
v-if="item.label === '新能源公司4'"
>
<el-input
v-model="scopeRows.row.Amount.Amount4"
type="number"
:disabled="rowID!=scopeRows.row.SubjectsID "
@blur="getRowData(scopeRows.row.Amount)"
oninput="value=value.replace(/^0|[^0-9]/g, '')"
></el-input>
</template>
<template
v-slot="scopeRows"
v-if="item.label === '定边风力公司5'"
>
<el-input
v-model="scopeRows.row.Amount.Amount5"
type="number"
@blur="getRowData(scopeRows.row.Amount)"
:disabled="rowID!=scopeRows.row.SubjectsID "
oninput="value=value.replace(/^0|[^0-9]/g, '')"
></el-input>
</template>
<!-- 入库登记用到的 inWarehouseRow: 在给表格赋值时定义的。 -->
<template
v-slot="scopeRows"
v-if="item.label === '购买数量'"
>
<el-input
v-model="scopeRows.row.inWarehouseRow.Quantity"
type="number"
@blur="getRowData(scopeRows.row.inWarehouseRow)"
oninput="value=value.replace(/^0|[^0-9]/g, '')"
></el-input>
</template>
<template
v-slot="scopeRows"
v-if="item.label === '单价'"
>
<el-input
v-model="scopeRows.row.inWarehouseRow.UnitPrice"
type="number"
@blur="getRowData(scopeRows.row.inWarehouseRow)"
oninput="value=value.replace(/[^\d.]/g, '').replace(/^0+(\d)/, '$1').replace(/^\./, '0.').replace('.', '$#$').replace(/\./g, '').replace('$#$', '.').replace(/^\./g, '')"
></el-input>
</template>
<template
v-slot="scopeRows"
v-if="item.label === '操作'"
>
<el-button
link
type="primary"
size="small"
color="#b0b1b3"
class="handleClick_Btn"
@click="handleClick(scopeRows.row)"
>保存</el-button>
</template>
</el-table-column>
<!-- 二级表头 -->
<el-table-column
v-else
:key="index + 1"
:prop="item.prop"
:label="item.label"
:type="item.type"
:align="item.align || 'center'"
>
<template v-for="(childItem, index) in item.Children">
<!-- 三级表头 -->
<el-table-column
v-if="!childItem.Children"
:key="index"
:prop="childItem.prop"
:label="childItem.label"
header-align="center"
:align="childItem.direction"
:min-width="childItem.width"
>
</el-table-column>
<el-table-column
v-else
:key="index + 1"
:prop="childItem.prop"
:label="childItem.label"
:type="childItem.type"
:align="childItem.align || 'center'"
>
<template v-for="(childItem, index) in item.Children">
<!-- 这是第三层 -->
<el-table-column
v-if="!childItem.Children"
:key="index"
:prop="childItem.prop"
:label="childItem.label"
header-align="center"
:align="childItem.direction"
:min-width="childItem.width"
>
</el-table-column>
<el-table-column
v-else
:key="index + 1"
:prop="childItem.prop"
:label="childItem.label"
:type="childItem.type"
:align="childItem.align || 'center'"
>
</el-table-column>
</template>
</el-table-column>
</template>
</el-table-column>
</template>
<!-- 表格最后一列是否是勾选框【完成情况】 -->
<el-table-column
v-if="isSelect"
align="center"
>
<template
slot="header"
slot-scope="scope"
>
<el-checkbox
@change="allCheck(isAllcheck, tableData, ClickIdsList, isIndeterminate)"
size="large"
v-model="isAllcheck"
:indeterminate="isIndeterminate"
></el-checkbox>
完成情况
</template>
<template slot-scope="scope">
<!-- <el-button @click="Ones(scope)">122333</el-button> -->
<el-checkbox
@change="OnesClick(scope.row)"
v-model="scope.row.check"
class="ml-4"
size="large"
></el-checkbox>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<div v-if="showFenYe">
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="page.currentPage"
:page-sizes="[5, 10, 15, 20]"
:page-size="page.pagesize"
layout="total, sizes, prev, pager, next, jumper"
:total="page.total"
>
</el-pagination>
</div>
</div>
</template>
<script>
// import preventBack from "vue-prevent-browser-back"; //阻止返回
import { PublicFunction } from "@/utils/vuePublic";
export default {
name: "maintenPublictable",
components: {},
props: {
// 接收的是:是否有分页、是否有勾选
columns: {
type: Object,
default: {},
},
// 接收的是:页码
pagination: {
type: Object,
default: {},
},
// 接收的是:传递过来的库位数据
storageLocationSelect: {
type: Array,
default: [],
},
// 接收的是:传递过来的库位数据
GoodsID: {
type: Array,
default: [],
},
// 接收的是:传递过来的计划编制的行点击的id
SubjectsID: {
type: Number,
default: "",
},
},
data() {
return {
tableHeader: [], //表头
tableData: [], //数据
itemKey: "",
types: 1, //用于合并,判断是否需要合并
//#region 与父组件关联
getHeight: 20, //高度
isSelect: false, //勾选框
showFenYe: false, //是否有分页
isSelection: false, //是否有多选框
isTag: false, //是否有标签
defaultall: false, //是否默认展开所有行(用于有树状结构的表格)
highlightCurrent: false, //高亮选中
//#endregion
// 页码
page: {
currentPage: 1, //当前页
pagesize: 5, //当前页的条数
total: 20, //总数
},
//多选框
multipleSelection: [],
//#region 用于右侧的完成情况
//选择
isAllcheck: false, //全选
ClickIdsList: [], //已选择集合组
isIndeterminate: false, //部分选中,默认是false
//#endregion,
//仓库对应的库位数据
StorageLocation: [],
// //选中的行
// 行id
rowID: null,
disableD: true,
//#endregion
};
},
// mixins: [preventBack], //注入 阻止返回上一页
created() {},
watch: {
// 监听对象的写法(监听页码的变化)
pagination: {
handler(newValue, oldVal) {
// console.log("监听111", oldVal);
// console.log("监听222", newValue);
this.page.total = newValue.total;
},
deep: true, // 深度监听
// immediate: true, //写上它,初始化时也会调用监听
},
//接收库位的数据
storageLocationSelect: {
handler(n, o) {
this.StorageLocation = n;
},
deep: true, // 深度监听
immediate: true, //写上它,初始化时也会调用监听
},
},
mounted() {
this.init();
// console.log(this.columns, "初始化:接收父组件传过来的值", this.pagination);
},
methods: {
a(val, el) {
console.log(val, "zheshi ", el);
},
Test(val) {
console.log(val);
},
Ones(value) {
console.log("12121212", value);
},
//在父组件初始化时,需要获得页码,所以子组件初始化时把页码传过去
init() {
let _this = this;
_this.getHeight = this.columns.getHeight;
_this.defaultall = this.columns.defaultall; //是否展开所有行
_this.isSelect = this.columns.isSelect; //右侧的完成情况
_this.isTag = this.columns.isTag; //是否有标签
_this.showFenYe = this.columns.showFenYe;
_this.isSelection = this.columns.isSelection; //左侧的多选框
_this.highlightCurrent = this.columns.highlightCurrent; //高亮选中
_this.page.total = this.pagination.total;
_this.$emit("getPage", {
data: {
pageSize: _this.page.pagesize,
pageNum: _this.page.currentPage,
isTypes: 1,
},
});
// //每次使用就调一次
// this.SetDataTableHeader()
this.rowID = null;
},
//一页有多少条数据
handleSizeChange(val) {
let _this = this;
_this.page.pagesize = val;
// 子传父
_this.$emit("getPage", {
data: {
pageSize: _this.page.pagesize,
pageNum: _this.page.currentPage,
isTypes: 2,
},
});
},
//第几页/切换页码
handleCurrentChange(val) {
let _this = this;
_this.page.currentPage = val;
_this.$emit("getPage", {
data: {
pageSize: _this.page.pagesize,
pageNum: _this.page.currentPage,
isTypes: 2,
},
});
},
//表头
SetDataTableHeader(GetDataLists) {
//重新渲染,itemKey用于处理Table不渲染的问题
this.itemKey = Math.random();
//重新渲染数据表
this.tableHeader = GetDataLists;
// console.log("表头", this.tableHeader);
// this.$forceUpdate()
},
//table值
SettableData(tabledata, flag) {
// console.log(tabledata, "tabledata");
let _this = this;
_this.tableData = tabledata;
// console.log("接收父组件传过来的表格数据", tabledata);
this.tableData.forEach((item, index) => {
//仓库初始化编辑
item.editRow = {
InStockQuantity: "", //在库数量
InStockAmount: "", //在库金额
StoreLocationID: "", //库位
};
/**1是编辑,0是新增 */
if (flag == 1) {
item.inWarehouseRow = {
Quantity: item.Quantity,
UnitPrice: item.UnitPrice,
};
} else if (flag == 0) {
item.inWarehouseRow = {
Quantity: "",
UnitPrice: "",
};
}
//如果flag为true的情况下,是编辑,进行赋值, 为false是新增
if (flag == true) {
//计划编制的字段
item.Amount = {
Amount1: item.Amount1,
Amount2: item.Amount2,
Amount3: item.Amount3,
Amount4: item.Amount4,
Amount5: item.Amount5,
};
} else {
item.Amount = {
Amount1: "",
Amount2: "",
Amount3: "",
Amount4: "",
Amount5: "",
};
}
});
},
//左侧:多选框
handleSelectionChange(val) {
this.multipleSelection = val;
// console.log("左侧:勾选数据", this.multipleSelection);
this.$emit("handleSelectionChange", val);
},
//#region 下面这个是用于最右侧的完成情况
//全选 调取公共js文件的方法
allCheck(isAll, tableData, checkList, isCheck) {
//接收传过来的值
let objData = PublicFunction.allCheck(
isAll,
tableData,
checkList,
isCheck
);
this.isAllcheck = objData.isAll;
this.ClickIdsList = objData.checkList;
},
//单行选择
OnesClick(rows) {
if (rows.check) {
this.ClickIdsList.push(rows.id);
} else {
let index = this.ClickIdsList.indexOf(rows.id);
this.ClickIdsList.splice(index, 1);
}
// console.log("勾选111", this.ClickIdsList);
this.isIndeterminate =
this.ClickIdsList.length > 0 &&
this.ClickIdsList.length < this.tableData.length;
this.isAllcheck = this.ClickIdsList.length == this.tableData.length;
},
//#endregion
// 合并单元格
objectSpanMethod({ row, column, rowIndex, columnIndex }, tableData, types) {
if (types === 1) {
switch (
columnIndex // 将列索引作为判断值
) {
// 通过传递不同的列索引和需要合并的属性名,可以实现不同列的合并(索引0,1 指的是页面上的0,1)
case 2:
return PublicFunction.MergeCol(tableData, "itemDetail", rowIndex);
case 1:
return PublicFunction.MergeCol(tableData, "item", rowIndex);
}
} else {
//保障作业
switch (columnIndex) {
case 1:
return PublicFunction.MergeCol(tableData, "item", rowIndex);
}
}
//判断检查内容是否为空
// if (
// tableData[columnIndex].checkContent != undefined ||
// tableData[columnIndex].checkContent != null
// ) {
// } else {
// }
},
// 提交(在父组件点击提交时调用这个方法)
childSumbit() {
// console.log(
// "子组件提交",
// this.tableData,
// this.ClickIdsList,
// this.multipleSelection
// );
let param = {
tabledata: this.tableData,
ClickIdsList: this.ClickIdsList,
multipleSelection: this.multipleSelection,
};
// 把值传给父组件
this.$emit("sumbitData", param);
},
//行点击事件
clickRow(row, column, event) {
// let _this = this;
// _this.$router.push({
// name: "equipSchedule", //路由名称
// params: {
// data: row, //参数
// },
// });
this.rowID = row.SubjectsID;
this.$emit("rowClick", row);
},
// 行选中时间
handleCurrentChangeRow(val) {
this.$emit("handleCurrentChangeRow", val);
},
// 改变某一列的行的背景色
tableCellStyle({ row, column, rowIndex, columnIndex }) {
// console.log("背景色:");
// console.log("row===:", row);
// console.log("column===:", column);
// console.log("rowIndex===:", rowIndex);
// console.log("columnIndex===:", columnIndex);
//如果是第一列
if (columnIndex === 1) {
//如果这一行的字段==未维护
if (row.state == "未维护") {
// 如果是未维护——背景色浅蓝色,字体色蓝色;
return "background:#ecf5ff; color:#409eff";
} else if (row.state == "已维护") {
// 如果是已维护——背景色绿色,字体色白色;
return "background:#67c23aa6;color:#fff ";
} else if (row.state == "部分维护") {
// 如果是已维护——背景色棕色,字体色白色;
return "background:#e6a23cab;color:#fff ";
} else {
}
} else {
}
},
//获取行内编辑的数据
getRowData(val) {
console.log(val, "获取行内编辑的数据");
this.$emit("getEditRow", val);
},
/**
* 操作列
*/
handleClick(val) {
// console.log(val, "操作列");
this.$emit("getclickRow", val);
},
},
//#endregion
};
</script>
<style scoped>
.maintenPublictable ::v-deep .el-table th,
::v-deep .el-table thead.is-group th.el-table__cell {
background: linear-gradient(147deg, #70c0ff, #2f9fff);
color: #fff;
padding: 0;
margin: 0;
}
/*****滚动条影藏 */
::v-deep .el-table--scrollable-y ::-webkit-scrollbar {
display: none !important;
}
/**lable名字 */
::v-deep .el-checkbox__label {
color: #fff;
}
::v-deep .el-table__header {
height: 4rem;
}
/*按钮样式 */
/* ::v-deep .el-button:hover,
::v-deep .el-button:focus {
color: #f3f3f3 !important;
font-weight: bold;
} */
</style>