因为我有一个这样的表单,然后我很多页面都是一样的,所以我会将他封装为一套代码进行复用。
封装的代码如下:
<!-- NavForm.vue 头部搜索框的封装-->
<template>
<el-form :inline="true" :model="searchInfo" class="demo-form-inline" @keyup.enter.native="onSubmit">
<el-form-item
v-for="item in searColumns"
:key="item.model + item.label"
:label-width="item.labelWidth"
>
<el-input v-if="item.type === 'input'" v-model="searchInfo[item.model]" :placeholder="item.placeholder"
clearable></el-input>
<el-select v-if="item.type === 'select'" v-model="searchInfo[item.model]" :placeholder="item.placeholder"
clearable>
<el-option v-for="val in item.options" :key="val.value" :label="val.label" :value="val.value"></el-option>
</el-select>
<el-button v-if="item.type==='onSubmit'" icon="el-icon-search" type="primary" @click="onSubmit">查询
</el-button>
<el-button v-if="item.type==='onReset'" @click="onReset">重置</el-button>
</el-form-item>
<el-form-item
style="float: right"
v-for="item in searColumns"
:key="item.model"
:label-width="item.labelWidth"
>
<el-button v-if="item.type === 'add'" icon="el-icon-plus" type="primary" @click="addSubmit">{{ item.label }}
</el-button>
</el-form-item>
</el-form>
</template>
<script>
export default {
props: {
searColumns: {
type: Array,
required: true,
default: () => []
}
},
data() {
return {
searchInfo: {}
};
},
methods: {
onSubmit() {
this.$emit('submit', this.searchInfo);
},
onReset() {
this.searchInfo = {};
this.$emit('reset');
},
addSubmit() {
this.$emit('addSubmit',);
},
}
};
</script>
表单的使用:
<!--其中的searColumns搜索框的配置,submit为提交,reset为重置-->
<NavForm
:searColumns="searColumns"
@submit="onSubmit"
@reset="NoSubmit"
></NavForm>
<!--如何引入-->
import NavForm from "@/admin/components/NavForm.vue";
<!--searColumns搜索框的配置实例 其中需要输入框type为input select为下拉框-->
searColumns: [
{placeholder:'同步项ID', model: 'datasync_id',type: 'input'},
{placeholder: '状态', model: 'status',type: 'select', options: this.typeOptions}
],
<!--onSubmit需要获取子组件的数据 val用来赋值给父组件-->
onSubmit(val) {
this.page = 1;
if (this.searchInfo.datasync_id === "") {
this.searchInfo.datasync_id = null;
}
this.searchInfo = val;
this.GetSyncRecordList();
},
<!--上面的searColumns如果没有正确的拿到数据那么需要在mounted中赋值,示例:-->
mounted() {
this.searColumns = [
{placeholder:'同步项ID', model: 'datasync_id',type: 'input'},
{placeholder: '状态', model: 'status',type: 'select', options: this.typeOptions},
{type: 'onSubmit', label: '查询',},
{type: 'onReset', label: '重置',},
]
}
封装完了表单,那么我就开始封装表格了
表格的代码封装如下:
<template>
<div>
<el-table
ref="multipleTable"
:data="tableData"
:header-cell-style="{ background: '#F5F7FA' }"
tooltip-effect="dark"
border
@header-dragend="handleHeaderDragend"
@selection-change="handleSelectionChange"
:row-class-name="rowClassName"
>
<el-table-column
type="selection"
width="55">
</el-table-column>
<el-table-column
v-for="column in columns"
:key="column.prop"
:prop="column.prop"
:label="column.label"
:width="column.width"
:show-overflow-tooltip="column.showOverflowTooltip"
:align="column.align"
>
<!-- 使用作用域插槽来自定义列的内容 -->
<template v-slot="scope">
<slot :name="`column-${column.prop}`" :row="scope.row">
<!-- 这里是默认内容,当没有提供名为 `column-${column.prop}` 的插槽时显示 -->
{{ scope.row[column.prop] }}
</slot>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
export default {
name: 'CommonTable',
props: {
tableData: {
type: Array,//类型
required: true,//必填
default: () => []
},
columns: {
type: Array,//类型
required: true,//必填
default: () => []
}
},
data() {
return {
selectedRows: [] // 添加这一行
}
},
methods: {
// 选中的行
handleSelectionChange(selection) {
this.selectedRows = selection; // 更新被选中的行
// console.log(selection,'selection');
},
// 改变选中行的颜色
rowClassName({ row }) {
if (this.selectedRows.includes(row)) {
return 'row-selected';
}
return '';
},
// 拖拽表单自定义宽度的方法
handleHeaderDragend(newWidth, oldWidth, column, event) {
console.log(newWidth, oldWidth, column, event, 'newWidth, oldWidth, column, event')
// console.log(this.$route.name, '$route.name')
const columnKey = column.property;
const columnWidths = JSON.parse(localStorage.getItem(`${this.$route.name}-columnWidths`)) || {};
columnWidths[columnKey] = newWidth;
localStorage.setItem(`${this.$route.name}-columnWidths`, JSON.stringify(columnWidths));
},
applyColumnWidths(columns) {
// 应用列宽度的逻辑
const columnWidths = JSON.parse(localStorage.getItem(`${this.$route.name}-columnWidths`)) || {};
columns.forEach((column) => {
if (columnWidths[column.prop]) {
column.width = columnWidths[column.prop];
}
});
}
},
watch: {
columns: {
immediate: true,
handler(newColumns) {
this.applyColumnWidths(newColumns);
}
}
},
mounted() {
this.$nextTick(() => {
// 应用列宽度的逻辑// 获取自定义宽度的方法
const columnWidths = JSON.parse(localStorage.getItem(`${this.$route.name}-columnWidths`)) || {};
this.columns.forEach((column) => {
if (columnWidths[column.prop]) {
column.width = columnWidths[column.prop];
}
});
});
},
beforeDestroy() {
// 保存自定义宽度的方法
const columnWidths = {};
this.$refs.multipleTable.columns.forEach((column) => {
if (column.width) {
columnWidths[column.property] = column.width;
}
});
localStorage.setItem(`${this.$route.name}-columnWidths`, JSON.stringify(columnWidths));
}
}
</script>
<style lang="scss">
//表格里面的边框颜色改为透明
.el-table__body-wrapper .el-table__row .el-table__cell {
border-left-color: transparent !important;
border-right-color:transparent !important ;
}
//选中行的颜色
.el-table .row-selected {
background: #F5FAFA;
}
</style>
使用方法如下:
<CommonTable
:tableData="tableData"
:columns="tableColumns"
>
<!--个性化的插槽,比如给category_id添加一个tag -->
<template v-slot:column-category_id="{ row }">
<el-tag>{{ row.category_id }}</el-tag>
</template>
<!-- 个性化操作栏,比如我需要一个查看修改删除的操作栏-->
<template v-slot:column-actions="{ row }">
<el-button type="text" @click="viewItem(row)">查看</el-button>
<el-button type="text" @click = "deleteItem(row)" > 删除 </el-button>
<el-button type="text" @click = "editItem(row)" > 修改 </el-button>
</template>
</CommonTable>
<!--如何引入-->
import CommonTable from "@/admin/components/CommonTable.vue";
<!--tableData示例:-->
tableData: [],
<!--获取参数值之后:-->
this.tableData = res.data.data即可
<!--tableColumns示例:-->
tableColumns: [
{label: '同步项ID', prop: 'datasync_id', width: 'auto', showOverflowTooltip: true},
{label: '状态', prop: 'status', width: 'auto', showOverflowTooltip: true},
{label: '失败原因', prop: 'reason', width: 'auto', showOverflowTooltip: true},
// {label: '操作', prop: 'actions', width: 'auto'}
],