1.組件,BaseTable 下有兩個文件,index.vue ,extend.js
index.vue代碼
<template>
<div class="crud">
<!--crud頭部,包含列表標題和可操作按鈕-->
<el-row class="crud-header">
<!--<el-col :span="8">{{formTitle}}列表</el-col>-->
<el-col :span="24">
<el-button type="success" size="mini" v-if="gridBtnConfig.create" @click="createOrUpdate(null)">
<i class="el-icon-plus"></i> 新增
</el-button>
<!-- 標記為single的按鈕不需要禁用,不依賴選擇數據-->
<el-button :disabled="!item.single && multipleSelection.length === 0" size="mini"
@click="handleEmit(item.emitName,'outer')"
v-for="(item,index) in outerButton" :key="index" :type="item.type?item.type:'primary'">
<svg-icon v-if="item.icon" :icon-class="item.icon"></svg-icon>
{{item.name}}
</el-button>
<el-button :disabled="multipleSelection.length === 0" size="mini" v-if="gridBtnConfig.delete" type="danger"
@click="remove(2)">
<svg-icon icon-class="delete"></svg-icon>
刪除
</el-button>
</el-col>
</el-row>
<!--crud主體內容區,展示表格內容-->
<el-table
ref="multipleTable"
v-loading="listLoading" element-loading-text="請等待"
:data="showGridData"
@selection-change="handleSelectionChange"
border
:stripe="true"
:header-cell-style="{'textAlign':'center'}"
style="width: 100%">
<el-table-column
v-if="!hideMultiple"
fixed="left"
type="selection"
width="55">
</el-table-column>
<el-table-column
v-if="hideMultiple"
fixed="left"
label="序號"
type="index"
width="55">
</el-table-column>
<el-table-column
v-for="(item,index) in gridConfig"
:key="index"
:prop="item.prop"
:label="item.label"
:align="nameLeft(item.label)"
show-overflow-tooltip
:width="item.width?item.width:''">
<template slot-scope="scope">
<span v-if="item.filter" ref="yifutian">{{walkProperty(item.prop,scope.row)||walkProperty(item.prop,scope.row)==0? item.filter(walkProperty(item.prop,scope.row)) : '--'}}</span>
<Cell
v-if="item.render"
:row="scope.row"
:column="item"
:index="scope.$index"
:render="item.render"></Cell>
<span v-if="!item.render&&!item.filter">
<span v-if="!item.template" ref="yifutian">{{walkProperty(item.prop,scope.row)||walkProperty(item.prop,scope.row)==0 ? walkProperty(item.prop,scope.row) : '--'}}</span>
<a style="color: #1582cf;cursor: pointer;" v-else @click="handleEmit(item.emitName,'inner',scope.row)">{{walkProperty(item.prop,scope.row)||walkProperty(item.prop,scope.row)==0 ? walkProperty(item.prop,scope.row) : '--'}}</a>
</span>
</template>
</el-table-column>
<el-table-column v-if="!hideEditArea" label="操作" :width="gridEditWidth?gridEditWidth:200" fixed="right">
<template slot-scope="scope">
<el-tooltip v-if="gridBtnConfig.update" effect="dark" content="修改" placement="top">
<span style="color: #409EFF" class="edit-icon" @click="createOrUpdate(scope.row)"><svg-icon
icon-class="xg"></svg-icon></span>
</el-tooltip>
<el-tooltip v-if="gridBtnConfig.view" effect="dark" content="查看" placement="top">
<span style="color: #409EFF" class="edit-icon" @click="viewDetail(scope.row)"><svg-icon
icon-class="view"></svg-icon></span>
</el-tooltip>
<!--擴展按鈕,如果擴展按鈕設置了動態顯示隱藏的條件,則需要根據條件顯示隱藏-->
<el-tooltip v-for="(item,index) in innerButton" :key="index" :type="item.type?item.type:'primary'"
v-if="(!item.hideJudge)||(item.hideJudge && walkProperty(item.hideJudge.key,scope.row) === item.hideJudge.val && (item.hideJudge.key2 ? walkProperty(item.hideJudge.key2,scope.row) === item.hideJudge.val2 : true))"
effect="dark" :content="item.name" placement="top">
<span :style="{color:item.iconColor?item.iconColor:'#409EFF'}" class="edit-icon"
@click="handleEmit(item.emitName,'inner',scope.row)"><svg-icon
:icon-class="item.icon?item.icon:'xg'"></svg-icon></span>
</el-tooltip>
<el-tooltip v-if="gridBtnConfig.singleDelete" effect="dark" content="刪除" placement="top">
<span style="color: #F56C6C" class="edit-icon" @click="remove(1,scope.row)"><svg-icon
icon-class="delete"></svg-icon></span>
</el-tooltip>
</template>
</el-table-column>
</el-table>
<!--crud的分頁組件-->
<div class="crud-pagination">
<!--如果不是異步請求展示數據,需要隱藏分頁-->
<el-pagination
v-if="isAsync"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="currentPage"
:page-sizes="pageSizes?pageSizes:[10, 20, 30, 40]"
:page-size="currentPageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="dataTotal">
</el-pagination>
</div>
<!--crud按鈕觸發的表單彈窗-->
<BaseDialogForm :width="dialogWidth" :label-width="dialogLabelWidth" :title="dialogTitle" ref="dialogForm"
:config="formConfig"
:form-data="formModel"
@submit="dialogSubmit"></BaseDialogForm>
<!--查看詳情模態框-->
<gx-dialog
title="查看詳情"
:visible.sync="detailDialogVisible"
:width="dialogWidth ? dialogWidth : '1300px'">
<ViewDetail :config="infoConfig?infoConfig:formConfig" :data="detailData"></ViewDetail>
</gx-dialog>
<el-dialog
title="提示"
:close-on-click-modal="false"
:visible.sync="deletess"
width="400px">
<i class="el-icon-info" style="color:#E6A23C;"></i>
<span>此操作將永久刪除數據, 是否繼續?</span>
<span slot="footer" class="dialog-footer">
<el-button type="primary" @click="deletes" size="mini">確 定</el-button>
<el-button @click="qxss" size="mini">取 消</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import BaseDialogForm from '@/components/BaseDialogForm/index.vue'
import ViewDetail from '@/components/ViewDetail/index.vue'
import GxDialog from "../GxDialog/index"
/*用render渲染自定義template*/
import Cell from './expand';
export default {
name: "base-crud",
components: {
BaseDialogForm,
ViewDetail,
GxDialog,
Cell
},
props: [
//
'pageSizes',
// 表單標題,例如用戶、角色
'formTitle',
// 表單配置
'formConfig',
//詳情的字段配置
'infoConfig',
// 表單的model數據
'formData',
// 表格配置
'gridConfig',
// 表格按鈕配置
'gridBtnConfig',
// 表格死數據
'gridData',
// 數據接口
'apiService',
// 判斷是否是異步數據
'isAsync',
// 表格編輯區域寬度
'gridEditWidth',
// 是否隱藏表格操作
'hideEditArea',
// 自定義新增和修改操作,覆蓋組件內的新增和刪除邏輯
'selfCreateAndUpdate',
//是否顯示多選,若不顯示多選,則顯示列表序號
'hideMultiple',
//數據的id標識字符串
'idKey',
//表格獲取數據默認傳入的參數
'gridParams',
//
'Update',
// 禁止刪除的條件配置
'forbiddenData',
// 操作的模態框寬度
'dialogWidth',
// 操作模態框中的表單label寬度
'dialogLabelWidth',
// 狀態顏色區別配置數組:[[未處理],[已處理],[已過期],[其它狀態]]
'statusobj'
],
data() {
return {
// 新增修改模態框title
dialogTitle: '',
// 展示的表格數據,數據來源可能是父組件傳遞的固定數據,可能是接口請求數據
showGridData: [],
// 當前頁碼
currentPage: 1,
// 每頁顯示數量
currentPageSize: 10,
// 列表數據總數
dataTotal: 0,
// 選中行數據
selectedRow: '',
// 表單數據
formModel: {},
// 保留多選的表格數據
multipleSelection: [],
// 擴展按鈕,包括表格內按鈕和表格外的批量操作按鈕
innerButton: [],
outerButton: [],
// 詳情數據
detailData: {},
detailDialogVisible: false,
// 是否是新增
isCreate: true,
// 數據加載
listLoading: false,
// 查詢參數
searchParams: {},
//刪除的數據
ids: [],
//刪除的彈框
deletess: false,
color: true,
statusObj: ''
}
},
mounted() {
//初始化擴展按鈕
if (this.gridBtnConfig.expands && this.gridBtnConfig.expands.length > 0) {
//內部按鈕,只操作單行數據
this.innerButton = this.gridBtnConfig.expands.filter(item => item.editType === 'inner');
//外部按鈕,操作批量數據
this.outerButton = this.gridBtnConfig.expands.filter(item => item.editType === 'outer');
}
this.getData();
this.statusObj = this.statusobj ? this.statusobj : [['未提交'], ['已提交', '已批復', '審批通過', '待上報', '已批復', '已撤回'], ['審核中', '返回修改'], ['已上報', '待批復'], ['審批不通過']];
},
methods: {
nameLeft(name) {
let a = name.substr(name.length - 2, 2);
// console.log(name.indexOf('名稱'),a);
if (a == '名稱') {
return 'left'
} else {
return 'center'
}
},
// 獲取列表數據
getData() {
this.listLoading = true;
//沒有定義api,直接返回,不進行請求
if (!this.apiService) {
this.listLoading = false;
this.showGridData = this.gridData;
return;
}
let params = {
current: this.currentPage,
size: this.currentPageSize
};
params = Object.assign({}, params, this.gridParams, this.searchParams);
this.apiService.list(params).then(res => {
this.showGridData = res.page.list;
this.dataTotal = res.page.totalCount;
this.listLoading = false;
//請求數據完成
this.$emit('getDataOver', res.page.list);
});
},
//查詢
search(params) {
this.currentPage = 1
this.currentPageSize = 10
this.searchParams = Object.assign({}, params);
this.getData();
},
//清空查詢
clearSearch() {
this.searchParams = {};
this.getData();
},
// 查看詳情
viewDetail(row) {
this.detailData = Object.assign({}, row);
this.detailDialogVisible = true;
},
createOrUpdate(item) {
// 如果配置了覆蓋組件內新增和修改按鈕時執行
if (this.selfCreateAndUpdate) {
this.$emit('createOrUpdate', item);
return;
}
this.$refs.dialogForm.resetForm();
this.formModel = item ? Object.assign({}, item) : Object.assign({}, this.formData);
this.dialogTitle = (item ? '修改' : '新增') + this.formTitle;
this.isCreate = !item;
this.$refs.dialogForm.showDialog();
},
// 處理相應父組件的事件方法
handleEmit(emitName, type, row) {
// 如果是表格內按鈕,只需要回傳單行數據,表格外按鈕,則需要回傳批量數據
if (type === 'inner') {
this.$emit(emitName, row);
}
else {
this.$emit(emitName, this.multipleSelection);
}
},
handleCurrentChange(page) {
this.currentPage = page;
this.getData();
},
handleSizeChange(size) {
this.currentPageSize = size;
this.getData();
},
// 處理點擊行
handleRowClick(row, event, column) {
this.selectedRow = Object.assign({}, row);
},
// 模態框數據提交
dialogSubmit(data) {
if (this.Update) {
this.$emit('Update', data);
return;
}
this.apiService[this.isCreate ? 'create' : 'update'](data).then(res => {
this.$message.success(this.dialogTitle + '成功!');
this.getData();
this.$refs.dialogForm.hideDialog();
})
},
hideDialog() {
this.$refs.dialogForm.hideDialog();
},
//處理多選改變時
handleSelectionChange(val) {
this.multipleSelection = val;
},
// 切換當前行的選中狀態
toggleSelection(rows) {
if (rows) {
this.$nextTick(()=>{
rows.forEach(row => {
this.$refs.multipleTable.toggleRowSelection(row);
});
})
} else {
this.$refs.multipleTable.clearSelection();
}
},
//刪除方法
remove(type, data) {
this.ids = [];
//type為1代表單個刪除,2代表批量刪除
if (type === 1) {
this.ids = [data[this.idKey ? this.idKey : 'id']];
} else {
//如果上傳了禁止刪除的條件,進入下面條件處理
if (this.forbiddenData) {
let key = this.forbiddenData.key;
let arr = this.forbiddenData.data;
let boolean = false;
this.multipleSelection.forEach(item => {
arr.forEach(val => {
if (val === item[key]) {
return (boolean = true);
}
});
//如果已經有禁止刪除項,退出遍歷,優化性能
if (boolean) {
return false;
}
});
if (boolean) {
return this.$notify({
title: '警告',
message: '您選擇的數據包含禁止刪除項,請重新選擇數據進行刪除!!!',
type: 'warning',
position: 'top-left',
duration: 2000
});
}
}
this.ids = this.multipleSelection.map(item => item[this.idKey ? this.idKey : 'id']);
}
// this.$confirm('此操作將永久刪除數據, 是否繼續?', '提示', {
// showCancelButton: true,
// confirmButtonText: '確定',
// cancelButtonText: '取消',
// confirmButtonClass:'confirmButtonClass',
// type: 'warning'
// }).then(() => {
// this.apiService.delete(ids).then(res => {
// this.$message({
// type: 'success',
// message: '刪除成功!'
// });
//
// this.getData();
// })
// }).catch(() => {
// this.$message({
// type: 'info',
// message: '已取消刪除'
// });
//
//
// });
this.deletess = true
},
deletes() {
this.apiService.delete(this.ids).then(res => {
this.$message({
type: 'success',
message: '刪除成功!'
});
this.getData();
this.deletess = false
})
},
qxss() {
this.deletess = false
this.$message({
type: 'info',
message: '已取消刪除'
});
},
walkProperty(prop, data) {
//a.b
if (prop && prop.indexOf('.') !== -1) {
let path = prop.split('.'), i, v = data;//[a, b]
while (i = path.shift()) {
if (v && v[i]) {
v = v[i];
}
else {
v = '';
}
}
return v;
}
else {
return data[prop];
}
},
//清空多選
clearSelection() {
//清空多選的選中
this.$refs.multipleTable && this.$refs.multipleTable.clearSelection();
},
shangse() {
let i = 1;
let elementArrays = this.$refs.yifutian;
if (!elementArrays) {
return;
}
this.statusObj.forEach(obj => {
obj.forEach(obj2 => {
elementArrays.forEach(item => {
let str = item.innerText;
if (str === obj2) {
item.setAttribute('class', 'class' + i);
}
})
});
i++;
});
},
setGridParams(data) {
this.search(data);
}
},
watch: {
// 防止表格預置數據不成功,涉及生命周期問題
gridData() {
this.showGridData = this.gridData;
this.dataTotal = this.showGridData.length;
},
showGridData: function () {
this.$nextTick(function () {
this.shangse();
})
}
},
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
.crud {
.crud-header {
margin-bottom: 10px;
line-height: 40px;
}
.crud-pagination {
text-align: right;
margin-top: 10px;
}
/*表格內編輯圖標*/
.edit-icon {
font-size: 20px;
margin-right: 10px;
cursor: pointer;
}
/*未處理*/
.class1 {
color: #999999;
padding: 5px;
}
/*已處理*/
.class2 {
color: #06AC4D;
padding: 5px;
}
/*已過期*/
.class3 {
color: #FBBE42;
padding: 5px;
}
/*其它狀態*/
.class4 {
color: #3DB5FC;
padding: 5px;
}
.class5 {
color: #FC5454;
padding: 5px;
}
}
</style>
<style>
.confirmButtonClass {
color: #fff;
background-color: #0597D2 !important;
border-color: #0597D2 !important;
}
</style>
--extend.js代碼
export default { name: 'TableExpand', functional: true, props: { row: Object, render: Function, index: Number, column: { type: Object, default: null } }, render: (h, ctx) => { const params = { row: ctx.props.row, index: ctx.props.index }; if (ctx.props.column) params.column = ctx.props.column; return ctx.props.render(h, params); } };
2.以上是兩個組件的代碼,下面將介紹調用及傳入數據的格式
--調用組件
引入組件,且注冊組件
import BaseTable from '@/components/BaseTable/index.vue' 注冊加入components components: { BaseTable }, 調用組件 <BaseTable :api-service="informationApi" :grid-config="INFO_CONFIG.gridConfig" :grid-btn-config="INFO_CONFIG.gridBtnConfig" ref="crud" :grid-edit-width="80" :is-async="true" :hide-edit-area="true"> </BaseTable> 傳入數據的Js數據格式: const INFO_CONFIG = { gridConfig: [ {label: '設備代碼', prop: 'sbdm', width: '150'}, {label: '設備名稱', prop: 'sbmc'}, {label: '型號規格', prop: 'xh'}, {label: '計量單位', prop: 'jldw', filter: equipmentUnitFilter}, {label: '類型', prop: 'lx'}, {label: '廠家', prop: 'cj'}, {label: '是否是計量設備', prop: 'sfjlsb', filter: filterJLSB}, {label: '籌供單位', prop: 'cgdw', filter: filterGCDW}, {label: '使用年限(月)', prop: 'synx'}, ], //操作按鈕 gridBtnConfig: { create: false, update: false, delete: false, view: false } }
注意informationApi:是API 調用地址,如果需要直接傳入數據,需要更組件中的邏輯,apiService傳入true,不需要請求數據,出入gridData=[],即表格顯示的數據,組件中傳入的參數都寫了注釋,根據需做出更改吧
關注博客,后期更新Vue表單組件。
