效果图:
使用组件,启用自动生成 :auto="true"
自动生成-编辑 (包括请求已经实现了)新增和删除也是一样
ps:如有额外的按钮可以用插槽实现
查询的时候,只需要多返回下面数据,就可以自动生成列,和对应操作按钮
目录
table.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 |
<template> <div>
<el-row v-if="auto"> <el-col :span="4"> <el-button size="small" type="primary" @click="add(table.buttons.add)">新增</el-button> </el-col> <el-col :span="20"> <div style="display: flex;justify-content: flex-end;margin:10px 0 10px 0"> <slot name="search"></slot> <el-button size="small" type="primary" @click="filterData">查询</el-button> </div> </el-col> </el-row> <el-row v-else> <el-col :span="24" style="padding-top: 30px"> </el-col> </el-row>
<el-table v-if="auto" v-loading="table.loading" :data="table.data" style="width: 100%"> <el-table-column v-for="(item,index) in table.columns" :key="index" :label="item.label+'-自动生成'" :prop="item.prop"></el-table-column>
<el-table-column label="操作-自动生成"> <template slot-scope="scope"> <el-button size="small" type="button" @click="edit(scope.row,table.buttons.edit)">编辑</el-button> <el-button size="small" type="danger" @click="del(scope.row,table.buttons.del)">删除</el-button> </template> </el-table-column> </el-table>
<el-table v-if="!auto" v-loading="table.loading" :data="table.data" style="width: 100%"> <slot> <el-table-column label="默认列" ></el-table-column> </slot> </el-table> <el-pagination background :current-page="this.$parent.filters.pageIndex" layout="total, sizes, prev, pager, next, jumper" :page-size="this.$parent.filters.pageSize" style="width: 50%;margin:20px auto 0px auto;text-align: center;" :total="total" @current-change="handleCurrentChange" @size-change="handleSizeChange" /> </div> </template> <script>
export default ({ name:'table-test', props: { auto:{ type:Boolean, default:()=>false, }, query: { type: Function, default: ()=>null, }, }, created(){ this.filterData() }, data(){ return {
table:{ columns:[], buttons:{}, data:[], loading:false, }, total:0 } }, methods:{ handleCurrentChange(index) { this.$parent.filters.pageIndex = index this.filterData() }, handleSizeChange() {}, filterData(){ this.table.loading=true /* eslint-disable */ // debugger if(this.query){ this.query().then(res=>{ this.table.data = res.data this.table.columns =res.columns this.table.buttons =res.buttons this.total=res.totalCount }).finally(()=>{ this.table.loading=false }) }else{ console.error('table组件未设置query函数') } }, del(row,setting){ // this.table.data.splice(index,1) this.$baseConfirm('你确定要删除吗?', null, () => { this.fn(row,setting) }) }, add(setting){ // 约定添加、编辑弹窗组件都叫 addIndex或者一个其它统一的名称, 就可以实现通用 this.$parent.$refs.addIndex.show((form)=>this.fn(form,setting)) }, edit(row,setting){ this.$parent.$refs.addIndex.showEdit(()=>this.fn(row,setting),row) }, fn(row,setting){ if(!row){ throw 'fn:row is null' } Object.keys(setting.data).forEach(x=> { setting.data[x] = row[x] }) Object.keys(setting.param).forEach(x=> { setting.param[x] = row[x] }) this.request({ url:setting.url, mtehod:setting.method, param:setting.param, data:setting.data }).then((res)=>{ this.$message.success(res.message) this.filterData() }) }, //模拟请求 request(param){ console.log('request',param) return new Promise((res,rej)=>{ setTimeout(() => { res({code:200,data:null,message:'ok'}) }, 100); }) } } }) </script> <style lang="scss" scoped>
table button{ margin-top:10px; } ::v-deep{ .el-table .el-table__cell{ padding:8px 0; } .el-table__cell .el-button:first-child{ margin-left: 10px; } } </style> |
index.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
<template> <div id="app" style="width:1000px;background-color:cornsilk;margin:0 auto;padding:20px"> <div style="margin-top: 150px"></div>
<!-- 由后端接口返回的好处: 接口参数有任何变化,接口名称变更,后端直接更新即可,不用前端修改 ,减少了来回沟通的成本 组件提供了标准化,完整的基础功能,省去人为复制代码出现bug后修改的时间成本 省去的基础功能实现的细节,减少了功能细节缺胳膊少腿后期修补的时间成本 --> <!-- 使用 auto="true" 根据接口返回的配置【自动生成列,按钮,增删改查调用】不用再写任何代码 --> <myTable ref="table" :auto="true" :query="tableQuery"> <template slot="search"> <el-form :inline="true" label-width="50px" style="height: 40px"> <el-form-item label="id"> <el-input v-model="filters.id" placeholder="" style="width:200px"></el-input> </el-form-item> <el-form-item label="名称"> <el-input v-model="filters.name" placeholder="" style="width:200px"></el-input> </el-form-item> </el-form> </template> </myTable> <!-- 使用 auto="false" 需要自己定义列和增删改查函数 --> <myTable ref="table" :auto="false" :query="tableQuery"> <el-table-column label="id-插槽" prop="id"> </el-table-column> <el-table-column label="内容列-插槽" prop="name"></el-table-column> <el-table-column label="操作-插槽" > <template slot-scope="scope"> <el-button size="small" type="button" @click="edit(scope)">编辑</el-button> <el-button size="small" type="button" @click="edit(scope)">编辑</el-button> <el-button size="small" type="button" @click="edit(scope)">编辑</el-button> <el-button size="small" type="button" @click="edit(scope)">编辑</el-button> <el-button size="small" type="button" @click="edit(scope)">编辑</el-button> <el-button size="small" type="button" @click="edit(scope)">编辑</el-button> <el-button size="small" type="button" @click="edit(scope)">编辑</el-button>
<el-button size="small" type="danger" @click="del(scope.$index)">删除</el-button> </template> </el-table-column> </myTable> <addIndex ref="addIndex"></addIndex> </div> </template> <script> import addIndex from '@/views/components/add.vue' export default ({ name:'indexTest', components:{addIndex}, data(){ return { filters:{ pageIndex:1, pageSize:5 } } }, methods:{ //模拟请求返回 tableQuery(){ console.log('filters',this.filters) var p = new Promise((res,rej)=>{ console.log(rej) setTimeout(() => { var value ={ columns:[{label:'序号',prop:'id'},{label:'名称',prop:'name'}], buttons: { add:{ url:'/controller/add',method:'post',data:{id:'',name:''},param:{}}, edit:{ url:'/controller/update',method:'post',data:{id:'',name:''},param:{}}, del:{url:'/controller/delete',method:'delete', data:{ },param:{id:''}} }, data: [ {id:1,name:'测试1004' }, {id:2,name:'测试1009'}, // {id:3,name:'测试1009'}, // {id:4,name:'测试1009'}, // {id:5,name:'测试1009'}, // {id:6,name:'测试1009'}, // {id:7,name:'测试1009'}, // {id:8,name:'测试1009'}, // {id:9,name:'测试1009'}, // {id:10,name:'测试1009'}, ], totalCount:200};
value.data =value.data.filter(x=>this.where(x)) res(value) }, 1000); }) return p }, where(x){ var a = this.filters.id ? x.id == this.filters.id : true var b = this.filters.name ? x.name.indexOf( this.filters.name)>-1 : true var r = a && b return r }, edit(){}, del(){} } }) </script> <style lang="scss" scoped> table button{ margin-top:10px; } </style> |
add.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
<template>
<el-dialog :title="title" width="30%" :close-on-click-modal="false" :visible.sync="visible"> <el-form ref="form" :model="form" :rules="rules" :label-width="'120px'"> <el-form-item label="id" prop="id"> <el-input v-model="form.id" placeholder=""></el-input> </el-form-item> <el-form-item label="名称" prop="name"> <el-input v-model="form.name" placeholder=""></el-input> </el-form-item> </el-form> <div slot="footer" class="dialog-footer"> <el-button @click="visible = false">取 消</el-button> <el-button type="primary" @click="add()">确 定</el-button> </div> </el-dialog>
</template>
<script>
export default ({ name:'addTest', data(){ return { title:'新增', visible:false, form:{}, rules:{}, save:null, } }, methods:{ show(save,form){ this.visible=true this.save=save this.form =form?form:{} }, showEdit(save,form){ this.title='编辑' this.show(save,form) }, add(){ if(this.save!=null){ this.save(this.form) } else{ this.$message.success('ok2') } this.visible=false } } }) </script> |