基于element-ui的后台系统表格、dialog、筛选、自定义按钮、分页的一次性封装

方便基础业务开发封装的一套组件,基于vue2.5.x和element-ui,可以通过配置自动生成表格展示,表格新增、编辑功能、分页、筛选项、自定义显示表格数据等功能。

先上演示图片

----------------------------------

筛选部分

 

-----------------------------------------------------------

自定义按钮部分

 

--------------------------------

表格主体部分

 

 ------------

整体效果

 

以下为代码部分,都比较基础简单,就直接贴代码了

分别有,baseTable,baseDialogForm,customDisplay,filterGroup  4个小组件组成

baseTable部分(表格主体)

  1 <template>
  2     <div id="myTable">
  3         <filterGroup :filterList="filterConfig.filter_list" :search_list="filterConfig.search_list" v-on="{getFilterData:filterData}"></filterGroup>
  4         <div class="piliang">
  5             <router-link class="btn-link" v-for="item in topBtnConfig" :key="item.title" :to="item.jumpPage?item.jumpAddress:''">
  6                 <el-button type="primary" :icon="item.icon" v-if="item.jumpPage">{{item.title}}</el-button>
  7                 <el-button type="primary" :icon="item.icon" @click="createOrUpdate()" v-else>{{item.title}}</el-button>
  8             </router-link>
  9             <!-- 自定义显示 -->
 10             <customDisplay :customDisplayList="customDisplayList" v-on="{update_custom_display:updateCustomDisplay}"></customDisplay>
 11             <el-button class="float-right" @click="getData(true)" icon="el-icon-refresh" :loading="loading">更新数据</el-button>
 12         </div>
 13         <!--主体内容区,展示表格内容-->
 14         <el-table
 15             class="baseTable"
 16             :data="tableData"
 17             border
 18             size="small"
 19             v-loading="loading"
 20             tooltip-effect="dark"
 21             ref="table"
 22             @selection-change="handleSelectionChange"
 23         >
 24             <el-table-column type="selection" width="55" v-if="otherConfig.needSelect"></el-table-column>
 25             <el-table-column
 26                 v-for="(item,index) in tableConfig"
 27                 :key="index"
 28                 :prop="item.prop"
 29                 :label="item.label"
 30                 :width="item.width?item.''"
 31                 :min-width="item.minWidth?item.minWidth:''"
 32                 :sortable="item.sortable?true:false"
 33                 v-if="customDisplayList[index].show"
 34             >
 35                 <template slot-scope="scope">
 36                     <Cell v-if="item.render" :row="scope.row" :column="item" :index="scope.$index" :render="item.render"></Cell>
 37                     <span v-else>{{scope.row[item.prop]}}</span>
 38                 </template>
 39             </el-table-column>
 40             <el-table-column label="操作" v-if="tableBtnConfig.width" :width="tableBtnConfig.width" fixed="right" class-name="btns">
 41                 <template slot-scope="scope">
 42                     <!--扩展按钮-->
 43                     <el-button
 44                         @click="handleEmit(item.emitName, scope.row)"
 45                         v-if="tableBtnConfig.expands && tableBtnConfig.expands.length>0"
 46                         v-for="(item,index) in tableBtnConfig.expands"
 47                         :key="index"
 48                         :type="item.type?item.type:'primary'"
 49                     >{{item.name}}</el-button>
 50                     <el-button type="warning" v-if="tableBtnConfig.update&&!tableBtnConfig.isUpdateInNewPage" @click="createOrUpdate(scope.row)">编辑</el-button>
 51                     <el-button type="warning" v-else-if="tableBtnConfig.update&&tableBtnConfig.isUpdateInNewPage" @click="goTo(scope.row.id,tableBtnConfig.updateAddress)">编辑</el-button>
 52                     <el-button type="danger" v-if="tableBtnConfig.delete" @click.native="deleteItem(scope.row.id)">删除</el-button>
 53                 </template>
 54             </el-table-column>
 55         </el-table>
 56         <!-- 表格操作按钮 -->
 57         <div class="table-control-box">
 58             <el-button v-if="otherConfig.needSelect" type="info" @click="toggleSelection(tableData)">全选</el-button>
 59             <el-button v-if="otherConfig.needSelect" type="info" @click="batchDelete()">批量删除</el-button>
 60             <pagination class="float-right" :currentPaging="currentPaging" v-on="{sizeChange:handleSizeChange,currentChange:handleCurrentChange}"></pagination>
 61         </div>
 62         <!--按钮触发的表单弹窗-->
 63         <BaseDialogForm
 64             :title="dialogTitle"
 65             :width="formWidth"
 66             ref="dialogForm"
 67             :config="formConfig"
 68             :form-data="formModel"
 69             :err-form="formError"
 70             :is-edit="isEdit"
 71             @submit="dialogSubmit"
 72         ></BaseDialogForm>
 73     </div>
 74 </template>
 75 
 76 <script>
 77 import Cell from "./expand";
 78 import BaseDialogForm from "components/baseDialogForm";
 79 import customDisplay from "./customDisplay";
 80 // 分页
 81 import pagination from "components/pagination";
 82 import filterGroup from "components/filterGroup";
 83 
 84 export default {
 85     name: "baseTable",
 86     components: {
 87         Cell,
 88         BaseDialogForm,
 89         pagination,
 90         filterGroup,
 91         customDisplay
 92     },
 93     props: [
 94         // 表格配置
 95         "tableConfig",
 96         // 表格按钮配置
 97         "tableBtnConfig",
 98         // 数据接口
 99         "theApi",
100         // 其他表格配置
101         "otherConfig",
102         // 上方按钮配置
103         "topBtnConfig",
104         // 筛选项配置
105         "filterConfig",
106         // 表单标题,例如用户、角色
107         "formTitle",
108         "formWidth",
109         // 表单配置
110         "formConfig",
111         //  表格编辑区域宽度
112         "gridEditWidth",
113         // 表单的model数据
114         "formData"
115     ],
116     data() {
117         return {
118             //  表格加载状态
119             loading: false,
120             // 表格展示数据
121             tableData: [],
122             multipleSelection: [],
123             // 全选数据容器
124             allSelect: false,
125             // 筛选项
126             filter_data: {},
127             // 分页
128             currentPaging: { currentPage: 1, pageSize: 10, totals: 0 },
129             // 新增修改模态框title
130             dialogTitle: "",
131             // 表单数据
132             formModel: {},
133             // 后台输出错误信息
134             formError: {},
135             // 是否是编辑
136             isEdit: false,
137             // 自定义显示数据
138             customDisplayList: []
139         };
140     },
141     created() {
142         this.getData();
143         this.customInit(this.tableConfig);
144     },
145     methods: {
146         // 根据表格配置生成自定义显示数组
147         customInit: function(arr = []) {
148             this.customDisplayList = arr.map(item => {
149                 return {
150                     show: true,
151                     label: item.label
152                 };
153             });
154         },
155         // 获取列表数据
156         getData: async function(update = false) {
157             this.loading = true;
158             // 默认数据
159             let default_data = {
160                 page: this.currentPaging.currentPage,
161                 per_page: this.currentPaging.pageSize
162             };
163             // 筛选数据
164             let data = Object.assign(default_data, this.filter_data);
165             const res = await this.theApi.getData(data);
166             this.loading = false;
167             if (res.code === 200) {
168                 update && this.$message.success("数据已更新");
169                 const respon = res || {};
170                 this.tableData = respon.data || []; // 给表格赋值
171                 respon.total && (this.currentPaging.totals = respon.total);
172             }
173         },
174         // 新增 编辑按钮
175         createOrUpdate(item) {
176             this.$refs.dialogForm.resetForm();
177             item
178                 ? this.getEditData(item.id, () => {
179                         this.$refs.dialogForm.showDialog();
180                   })
181                 : this.$refs.dialogForm.showDialog();
182             item ? (this.isEdit = true) : (this.isEdit = false);
183             this.dialogTitle = (item ? "编辑" : "添加") + this.formTitle;
184         },
185         // 从后台获取编辑框需要的数据,表格只用作展示作用,所以不从表格内获取数据
186         getEditData: async function(id, callback) {
187             const res = await this.theApi.getEdit(id);
188             if (res.code === 200) {
189                 this.formModel = Object.assign({}, res.data[0] || {});
190                 callback && callback();
191             }
192         },
193         // 模态框数据提交
194         dialogSubmit: async function(data) {
195             // 根据是否有id判断是新增还是编辑
196             const res = await this.theApi[data.id ? "editItem" : "addItem"](
197                 data
198             );
199             if (res.code === 200) {
200                 this.getData();
201                 this.$message.success(this.dialogTitle + "成功!");
202             } else {
203                 // 在表单中输出错误提示
204                 const errList = res.errors || "";
205                 if (errList) {
206                     for (let key in errList) {
207                         errList[key] = errList[key][0];
208                     }
209                     this.formError = errList;
210                 }
211             }
212         },
213         // 处理相应父组件的事件方法
214         handleEmit(emitName, row) {
215             this.$emit(emitName, row);
216         },
217         // 编辑跳转页面
218         goTo: function(id, url) {
219             this.$router.push({
220                 path: url,
221                 query: { id: id }
222             });
223         },
224         // 删除
225         deleteItem: function(id) {
226             this.$confirm("是否删除?", "提示", {
227                 confirmButtonText: "确定",
228                 cancelButtonText: "取消",
229                 type: "warning"
230             })
231                 .then(() => {
232                     //ajax
233                     this.theApi.deleteItem({ id: id }).then(() => {
234                         if (res.code === 200) {
235                             this.$message.success("删除成功");
236                             // 刷新数据
237                             this.getData();
238                         }
239                     });
240                 })
241                 .catch(() => {
242                     this.$message.info("取消删除");
243                 });
244         },
245         // 批量删除
246         batchDelete: function() {
247             if (this.multipleSelection[0]) {
248                 this.$confirm("是否删除选择的条目?", "提示", {
249                     confirmButtonText: "确定",
250                     cancelButtonText: "取消",
251                     type: "warning"
252                 })
253                     .then(() => {
254                         let data = this.multipleSelection;
255                         //ajax
256                     })
257                     .catch(() => {
258                         this.$message.info("取消删除");
259                     });
260             } else {
261                 this.$message.error("请先选择要删除的条目");
262             }
263         },
264         // 表格选择
265         handleSelectionChange: function(val) {
266             this.multipleSelection = val;
267             this.allSelect = val.length === this.tableData.length;
268         },
269         // 全选按钮
270         toggleSelection: function(rows) {
271             if (rows && !this.allSelect) {
272                 rows.forEach(row => {
273                     this.$refs.table.toggleRowSelection(row, true);
274                 });
275             } else {
276                 this.$refs.table.clearSelection();
277             }
278         },
279         // 分页sizeChange
280         handleSizeChange: function(val) {
281             this.currentPaging.pageSize = val;
282             this.currentPaging.currentPage = 1;
283             // 更新数据
284             this.getData();
285         },
286         // 分页currentChange
287         handleCurrentChange: function(val) {
288             this.currentPaging.currentPage = val;
289             // 更新数据
290             this.getData();
291         },
292         // 更新自定义显示组件数据
293         updateCustomDisplay: function(arr) {
294             this.customDisplayList = arr;
295         },
296         // 筛选
297         filterData: function(obj) {
298             this.tableData = [];
299             this.filter_data = JSON.parse(JSON.stringify(obj));
300             this.currentPaging.currentPage = 1;
301             // 刷新数据
302             this.getData();
303         }
304     }
305 };
306 </script>
307 
308 <style lang="less" scoped>
309 @import "~assets/css/mixin.less";
310 .baseTable {
311      100%;
312     margin: 0.55rem 0;
313     /* 强制不换行 */
314     .btns {
315         .cell {
316             white-space: nowrap;
317         }
318     }
319     /deep/ thead {
320         th {
321             background: lighten(#ebeef5, 3%);
322             color: #333;
323             font-size: 14px;
324         }
325     }
326     .icon-text {
327         .iconfont {
328             font-size: 14px;
329             margin-right: 5px;
330         }
331     }
332 }
333 .table-control-box {
334     overflow: hidden;
335 }
336 .piliang {
337     margin: 0.55rem 0;
338     position: relative;
339     &::after {
340         .clear;
341     }
342     .btn-link {
343         margin-right: 10px;
344         float: left;
345     }
346     .el-button {
347         margin-left: 0;
348     }
349 }
350 </style>
View Code

customDisplay部分(自定义显示按钮)

  1 <template>
  2     <div id="customDisplay" class="float-left">
  3         <el-button type size="mini" class="float-left" icon="el-icon-setting" @click="customDisplayShow = !customDisplayShow">自定义显示</el-button>
  4         <div class="custom-display-dialog float-left" v-if="customDisplayShow">
  5             <ul class="custom-display-dialog-list">
  6                 <li class="item title">当前展示的信息</li>
  7                 <li class="item">
  8                     <el-checkbox v-model="checkedAll" @change="selectAll">全选</el-checkbox>
  9                 </li>
 10                 <li class="item" v-for="(item,index) in list" :key="index">
 11                     <el-checkbox v-model="item.show" @change="select">{{item.label}}</el-checkbox>
 12                 </li>
 13             </ul>
 14             <!-- model -->
 15             <div class="model" @click="customDisplayShow = false"></div>
 16         </div>
 17     </div>
 18 </template>
 19 
 20 <script>
 21 export default {
 22     // 自定义选择组件
 23     name: "customDisplay",
 24     data() {
 25         return {
 26             customDisplayShow: false,
 27             checkedAll: true,
 28             list: []
 29         };
 30     },
 31     props: ["customDisplayList"],
 32     created: function() {
 33         this.customDisplayList &&
 34             (this.list = JSON.parse(JSON.stringify(this.customDisplayList)));
 35     },
 36     methods: {
 37         // 全选
 38         selectAll: function() {
 39             this.list.map(item => {
 40                 item.show = this.checkedAll;
 41             });
 42             this.$emit("update_custom_display", this.list);
 43         },
 44         // 单选
 45         select: function() {
 46             let _list = this.list;
 47             for (let i = 0; i < _list.length; i++) {
 48                 if (!_list[i].show) {
 49                     this.checkedAll = false;
 50                     break;
 51                 } else {
 52                     this.checkedAll = true;
 53                 }
 54             }
 55             this.$emit("update_custom_display", this.list);
 56         }
 57     }
 58 };
 59 </script>
 60 <style lang="less" scoped>
 61 @import "~assets/css/mixin.less";
 62 #customDisplay {
 63     margin-right: 10px;
 64     .custom-display-dialog {
 65         margin-left: 10px;
 66         position: relative;
 67         z-index: 2200;
 68         .custom-display-dialog-list {
 69             position: absolute;
 70             z-index: 998;
 71             padding: 10px 20px;
 72             background: #fff;
 73             border: 1px solid #ccc;
 74             border-radius: 4px;
 75             box-shadow: 0 0 30px rgba(0, 0, 0, 0.15);
 76             .item {
 77                 margin: 2px 0;
 78                 .el-checkbox {
 79                     display: block;
 80                 }
 81             }
 82             .title {
 83                 font-size: 16px;
 84                 white-space: nowrap;
 85                 margin-bottom: 10px;
 86                 color: #888;
 87                 padding-right: 5px;
 88             }
 89         }
 90         .model {
 91              100%;
 92             height: 100%;
 93             position: fixed;
 94             top: 0;
 95             left: 0;
 96             z-index: 997;
 97         }
 98     }
 99 }
100 </style>
View Code

baseDialogForm部分(基于表格的弹出框表单)

  1 <template>
  2     <el-dialog :title="title" :visible.sync="dialogVisible" :width="width?'80%'">
  3         <el-form :model="formModel" ref="configForm" label-width="100px">
  4             <el-row :gutter="16">
  5                 <el-col :span="item.span?item.span:8" v-for="(item,index) in config" :key="index">
  6                     <el-form-item :prop="item.prop" :rules="item.rules" :label="item.label">
  7                         <!--输入框表单类型-->
  8                         <el-input
  9                             v-if="item.type === 'text' || item.type === 'password' || item.type === 'textarea'"
 10                             :type="item.type"
 11                             v-model="formData[item.prop]"
 12                             :placeholder="item.placeholder?item.placeholder:'请输入'"
 13                         ></el-input>
 14                         <!-- 计数器 -->
 15                         <el-input-number v-if="item.type === 'el-input-number'" v-model="formData[item.prop]" :min="1" :step="1" label="描述文字"></el-input-number>
 16                         <!--checkbox表单类型-->
 17                         <el-checkbox-group v-if="item.type === 'checkbox'" v-model="formData[item.prop]" :placeholder="item.placeholder?item.placeholder:'请选择'">
 18                             <el-checkbox v-for="option in item.data" :label="option.id" :key="option.id">{{option.name}}</el-checkbox>
 19                         </el-checkbox-group>
 20                         <!--radio表单类型-->
 21                         <el-radio-group v-if="item.type === 'radio'" v-model="formData[item.prop]" :placeholder="item.placeholder?item.placeholder:'请选择'">
 22                             <el-radio v-for="option in item.data" :label="option.id" :key="option.id">{{option.name}}</el-radio>
 23                         </el-radio-group>
 24                         <!--下拉选择类型-->
 25                         <el-select v-if="item.type === 'select'" v-model="formData[item.prop]" :placeholder="item.placeholder?item.placeholder:'请选择'">
 26                             <el-option v-for="option in item.data" :key="option.id" :label="option.label" :value="option.id"></el-option>
 27                         </el-select>
 28                         <el-date-picker v-if="item.type === 'datepicker'" v-model="formData[item.prop]" type="date" :placeholder="item.placeholder?item.placeholder:'请选择日期'"></el-date-picker>
 29                     </el-form-item>
 30                 </el-col>
 31             </el-row>
 32         </el-form>
 33 
 34         <span slot="footer" class="dialog-footer">
 35             <el-button @click="dialogVisible = false">取 消</el-button>
 36             <el-button type="primary" @click="submitForm(formModel)">确 定</el-button>
 37         </span>
 38     </el-dialog>
 39 </template>
 40 
 41 <script>
 42 export default {
 43     name: "base-dialog-form",
 44     props: [
 45         "title",
 46         "width",
 47         "visible",
 48         "config",
 49         "formData",
 50         "errForm",
 51         "isEdit"
 52     ],
 53     data() {
 54         return {
 55             formModel: {},
 56             dialogVisible: false,
 57             dialogTitle: ""
 58         };
 59     },
 60     mounted() {
 61         // 将组件上的属性赋值给当前组件内变量,因为props只能单向绑定,还需要监听属性值变化进行父子组件间交互
 62         this.formModel = this.formData;
 63         this.dialogVisible = this.visible;
 64         this.dialogTitle = this.title;
 65     },
 66     methods: {
 67         // 提交表单数据
 68         submitForm(obj) {
 69             console.log(obj);
 70             this.$refs.configForm.validate(valid => {
 71                 if (valid) {
 72                     // 让父组件接收到响应数据
 73                     this.$emit("submit", this.formModel);
 74                     // 关闭模态框
 75                     this.dialogVisible = false;
 76                 } else {
 77                     return false;
 78                 }
 79             });
 80         },
 81         // 重置表单状态
 82         resetForm() {
 83             if (this.$refs.configForm) {
 84                 this.$refs.configForm.resetFields();
 85             }
 86         },
 87         // 展示模态框
 88         showDialog() {
 89             this.dialogVisible = true;
 90         }
 91     },
 92     watch: {
 93         /*实现表单数据的绑定,实时接收父组件的数据变化*/
 94         formData() {
 95             this.formModel = this.formData;
 96         }
 97     }
 98 };
 99 </script>
100 
101 <style lang="less" scoped>
102 .el-input {
103      100% !important;
104 }
105 
106 .el-select {
107      100% !important;
108 }
109 </style>
View Code

filterGroup部分(表格上方筛选项集合)

  1 <template>
  2     <div id="filterGroup">
  3         <div class="filter-container" :class="{'opened':open,'big':open_btn_show}">
  4             <!-- 筛选项 -->
  5             <el-form :inline="true" id="formBox" ref="filterForm">
  6                 <el-form-item label="关键字:" v-if="filterOptions.search">
  7                     <el-input v-popover:popover v-model="filterData.keyword" @keyup.enter.native="getFilterData()" placeholder="请输入关键字" clearable></el-input>
  8                     <el-popover ref="popover" placement="bottom" width="200" trigger="focus" popper-class="search-popover">
  9                         <div v-if="search_list[0]">
 10                             <p class="popover-title">支持的搜索条件</p>
 11                             <ul class="popover-list">
 12                                 <li class="popover-item" v-for="(item, index) in search_list" :key="index">{{item}}</li>
 13                             </ul>
 14                         </div>
 15                         <span v-else>暂无可搜索项</span>
 16                     </el-popover>
 17                 </el-form-item>
 18                 <el-form-item label="分类:" v-if="filterOptions.classify">
 19                     <el-select v-model="filterData.classify">
 20                         <el-option v-for="(item,index) in classifyList" :key="item.value" :label="item.label" :value="item.value"></el-option>
 21                     </el-select>
 22                 </el-form-item>
 23                 <el-form-item label="年份:" v-if="filterOptions.year">
 24                     <el-select v-model="filterData.year">
 25                         <el-option v-for="(item,index) in years" :key="index" :label="item" :value="item"></el-option>
 26                     </el-select>
 27                 </el-form-item>
 28                 <el-form-item label="激活状态:" v-if="filterOptions.activation">
 29                     <el-select v-model="filterData.activation">
 30                         <el-option v-for="(item,index) in activationList" :key="index.value" :label="item.label" :value="item.value"></el-option>
 31                     </el-select>
 32                 </el-form-item>
 33                 <el-form-item label="审核状态:" v-if="filterOptions.examine">
 34                     <el-select v-model="filterData.examine">
 35                         <el-option v-for="(item,index) in examineList" :key="index.value" :label="item.label" :value="item.value"></el-option>
 36                     </el-select>
 37                 </el-form-item>
 38                 <el-form-item label="操作人:" v-if="filterOptions.operator">
 39                     <el-select v-model="filterData.operator">
 40                         <el-option v-for="(item,index) in operatorList" :key="index.value" :label="item.label" :value="item.value"></el-option>
 41                     </el-select>
 42                 </el-form-item>
 43                 <el-form-item label="事件:" v-if="filterOptions.event">
 44                     <el-select v-model="filterData.event">
 45                         <el-option v-for="(item,index) in eventList" :key="index.value" :label="item.label" :value="item.value"></el-option>
 46                     </el-select>
 47                 </el-form-item>
 48                 <el-form-item label="影片推荐:" v-if="filterOptions.recommend">
 49                     <el-cascader :options="recommendList" v-model="filterData.recommend" style="100%;"></el-cascader>
 50                 </el-form-item>
 51                 <el-form-item label="日期:" v-if="filterOptions.date_scope" class="date-filter">
 52                     <el-date-picker
 53                         v-model="filterData.date_scope"
 54                         type="daterange"
 55                         align="right"
 56                         unlink-panels
 57                         range-separator="至"
 58                         start-placeholder="开始日期"
 59                         end-placeholder="结束日期"
 60                         format="yyyy-MM-dd"
 61                         value-format="yyyy-MM-dd"
 62                     ></el-date-picker>
 63                 </el-form-item>
 64                 <el-form-item :class="open_btn_show?'btn':''" v-if="!sure">
 65                     <el-button type="primary" @click="getFilterData()">查 询</el-button>
 66                     <el-button
 67                         v-if="open_btn_show"
 68                         type="primary"
 69                         plain
 70                         @click="open = !open;btn_text = !open?'展开':'收起'"
 71                         :icon="!open?'el-icon-arrow-down':'el-icon-arrow-up'"
 72                     >{{btn_text}}</el-button>
 73                 </el-form-item>
 74                 <el-form-item v-else>
 75                     <el-button type="primary" @click="getFilterData()">确 定</el-button>
 76                 </el-form-item>
 77             </el-form>
 78         </div>
 79         <!-- 筛选结果项 -->
 80         <div class="filter-result-container" v-if="filter_arr[0]">
 81             <ul class="list">
 82                 <li class="item filter-text">
 83                     <i class="iconfont icon-filter"></i>
 84                     <span>检索项:</span>
 85                 </li>
 86                 <li class="item" v-for="item in filter_arr" :key="item.key" v-if="item.title">
 87                     <el-tag :closable="canClearFilter !== false" size="small" class="tag" @close="closeTag(item)">{{`${item.title} : ${item.value}`}}</el-tag>
 88                 </li>
 89                 <li class="item filter-text clearAll" @click="closeAllTag" v-if="showClearAllBtn !== false">清空</li>
 90             </ul>
 91         </div>
 92     </div>
 93 </template>
 94 
 95 <script>
 96 // css
 97 import "components/filterGroup/style.css";
 98 
 99 export default {
100     // 筛选项
101     name: "filterGroup",
102     data() {
103         return {
104             // 布局状态
105             menuType: 1,
106             contentWidthType: "流式",
107             isCollapse: false, // 导航是否折叠
108             open: false,
109             btn_text: "展开",
110             open_btn_show: false,
111             // 映射表
112             filterOptions: {
113                 search: false, // 关键字搜索
114                 classify: false, // 分类
115                 year: false, // 年份
116                 activation: false, // 激活状态
117                 examine: false, // 审核状态
118                 recommend: false, // 影片推荐
119                 operator: false, // 操作人
120                 event: false, // 事件
121                 date_scope: false // 日期选择范围
122             },
123             // 点击查询之后传到父级的筛选项数据
124             filterData: {},
125             // 筛选项数组
126             filter_arr: [],
127             // 分类
128             classifyList: [],
129             // 年份
130             years: [],
131             // 激活状态
132             activationList: [
133                 {
134                     value: 1,
135                     label: "已激活"
136                 },
137                 {
138                     value: -1,
139                     label: "未激活"
140                 }
141             ],
142             // 审核状态
143             examineList: [
144                 {
145                     value: 1,
146                     label: "已通过"
147                 },
148                 {
149                     value: 0,
150                     label: "未审核"
151                 },
152                 {
153                     value: -1,
154                     label: "驳回"
155                 }
156             ],
157             // 影片推荐
158             recommendList: [],
159             // 操作人
160             operatorList: [],
161             // 事件
162             eventList: []
163         };
164     },
165     props: {
166         // 筛选项配置 外部传入
167         filterList: Array,
168         search_list: Array, // 搜索框支持的搜索项
169         sure: true,
170         showClearAllBtn: true, // 是否显示清空按钮
171         canClearFilter: true // 是否能清除单个筛选
172     },
173     watch: {
174         listenContentWidthType(newVal) {
175             this.contentWidthType = newVal;
176             this.showBtn();
177         },
178         listenMenuType(newVal) {
179             this.menuType = newVal;
180             this.showBtn();
181         },
182         listenMenuCollapse(newVal) {
183             this.isCollapse = newVal;
184             this.showBtn();
185         }
186     },
187     computed: {
188         listenContentWidthType() {
189             return this.$store.state.contentWidthType;
190         },
191         listenMenuType() {
192             return this.$store.state.menuType;
193         },
194         listenMenuCollapse() {
195             return this.$store.state.menuCollapse;
196         },
197         role() {
198             return this.$store.state.role;
199         }
200     },
201     created: function() {
202         // 匹配显示
203         for (let key in this.filterOptions) {
204             for (let k in this.filterList) {
205                 if (this.filterList[k] == key) {
206                     this.filterOptions[key] = true;
207                 }
208             }
209         }
210     },
211     mounted: function() {
212         const that = this;
213         // 首页带参数筛选
214         let default_filter = function() {
215             // 首页带参数的跳转
216             if (that.$route.query.show_filter === "1") {
217                 if (that.open_btn_show) {
218                     that.open = true;
219                     that.btn_text = "收起";
220                 }
221                 let homePageFilterObj = {};
222                 that.filterData = homePageFilterObj;
223                 that.$emit("getFilterData", that.filterData);
224                 that.initFilter(that.filterData);
225             }
226         };
227         that.showBtn(default_filter);
228     },
229     methods: {
230         // 判断是否需要显示展开收起按钮
231         showBtn: function(callback) {
232             // 加上300的延时 因为css切换的过渡时间是.3s
233             setTimeout(() => {
234                 const formContainer = document.getElementById("formBox");
235                 this.open_btn_show =
236                     formContainer.clientHeight > 50 ? true : false;
237                 // 回调函数
238                 callback && callback();
239             }, 310);
240         },
241         // 传递筛选数据
242         getFilterData() {
243             let obj = this.filterData;
244             for (let key in obj) {
245                 if (obj[key] === "" || obj[key] === null) {
246                     delete obj[key];
247                 } else {
248                     if (key === "date_scope") {
249                         // 拆分数组
250                         const [exam_start_time, exam_end_time] = obj[key];
251                         Object.assign(
252                             obj,
253                             { exam_start_time },
254                             { exam_end_time }
255                         );
256                     }
257                 }
258             }
259             this.$emit("getFilterData", obj);
260             this.initFilter(obj);
261         },
262         // 生成筛选项列表数据
263         initFilter: function(filterList = {}) {
264             const filter_list = filterList;
265             let arr = [];
266             for (let key in filter_list) {
267                 if (
268                     filter_list[key] !== "" &&
269                     filter_list[key] !== undefined &&
270                     filter_list[key] !== null
271                 ) {
272                     arr.push({
273                         key: key,
274                         title: this.filterMap(key, filter_list[key]).title,
275                         value: this.filterMap(key, filter_list[key]).value
276                     });
277                 }
278             }
279             this.filter_arr = arr;
280         },
281         // 筛选项列表字典
282         filterMap: function(theKey = "", theValue) {
283             const key = theKey;
284             const val = theValue;
285             let item = {};
286             switch (key) {
287                 case "keyword":
288                     item.title = "关键字";
289                     item.value = val;
290                     break;
291                 case "date_scope":
292                     item.title = "日期";
293                     item.value = `${val[0]} - ${val[1]}`;
294                     break;
295                 case "activation":
296                     item.title = "激活状态";
297                     item.value = this.arrayMapFilter(
298                         this.activationList,
299                         val
300                     ).label;
301                     break;
302                 default:
303                     item = {};
304             }
305             return item;
306         },
307         // 筛选项字典内filter
308         arrayMapFilter: function(list = [], value = "") {
309             const arr = JSON.parse(JSON.stringify(list));
310             let val = value;
311             arr.filter(el => {
312                 if (el.value == val) {
313                     val = el;
314                 }
315             });
316             return val;
317         },
318         // 关闭筛选
319         closeTag: function(item) {
320             let key = item.key;
321             // 关联字段清除
322             if (item.key == "agent_id") {
323                 //
324             } else {
325                 delete this.filterData[key];
326             }
327             this.getFilterData();
328         },
329         // 清空筛选
330         closeAllTag: function() {
331             this.filterData = {};
332             this.getFilterData();
333         }
334     }
335 };
336 </script>
View Code

页面调用

  1 <template>
  2     <div id="member_list">
  3         <!-- 表格 -->
  4         <baseTable
  5             :theApi="table_ajax"
  6             :table-config="configData.tableConfig"
  7             :top-btn-config="configData.topBtnConfig"
  8             :table-btn-config="configData.tableBtnConfig"
  9             :other-config="configData.otherConfig"
 10             :filter-config="configData.filterConfig"
 11             :grid-edit-width="200"
 12             form-title="会员"
 13             form-width="40%"
 14             :form-config="configData.formConfig"
 15             :form-data="configData.formModel"
 16             @checkRegistration="checkRegistration"
 17             ref="basetable"
 18         ></baseTable>
 19     </div>
 20 </template>
 21 <script>
 22 // api
 23 import * as theApi from "api/enroll/member_list";
 24 import baseTable from "components/baseTable";
 25 // 类型验证
 26 import { checkActivation, checkEntry } from "utils/checkTypes";
 27 // 表单验证
 28 import { checkUserName } from "utils/verify";
 29 export default {
 30     name: "member_list",
 31     data() {
 32         return {
 33             //表格配置
 34             configData: {
 35                 // 其他配置
 36                 otherConfig: {
 37                     needSelect: true // 是否可以多选
 38                 },
 39                 // 表格数据配置
 40                 tableConfig: [
 41                     { label: "ID", prop: "id",  "70" },
 42                     { label: "用户名", prop: "username" },
 43                     { label: "昵称", prop: "nickname" },
 44                     { label: "注册时间", prop: "datetime", sortable: true },
 45                     {
 46                         label: "会员激活状态",
 47                         prop: "member_type",
 48                         render: (h, params) => {
 49                             const { color, text, icon } = checkActivation(
 50                                 params.row.member_type
 51                             );
 52                             return (
 53                                 <div class="icon-text">
 54                                     <i
 55                                         class={`iconfont icon-${icon}`}
 56                                         style={`color:${color}`}
 57                                     />
 58                                     <span style={`color:${color}`}>{text}</span>
 59                                 </div>
 60                             );
 61                         }
 62                     },
 63                     {
 64                         label: "D20报名状态",
 65                         prop: "d20_type",
 66                         render: (h, params) => {
 67                             const { color, text, icon } = checkEntry(
 68                                 params.row.d20_type
 69                             );
 70                             return (
 71                                 <div class="icon-text">
 72                                     <i
 73                                         class={`iconfont icon-${icon}`}
 74                                         style={`color:${color}`}
 75                                     />
 76                                     <span style={`color:${color}`}>{text}</span>
 77                                 </div>
 78                             );
 79                         }
 80                     },
 81                     {
 82                         label: "IDF创投报名状态",
 83                         prop: "idf_type",
 84                         render: (h, params) => {
 85                             const { color, text, icon } = checkEntry(
 86                                 params.row.idf_type
 87                             );
 88                             return (
 89                                 <div class="icon-text">
 90                                     <i
 91                                         class={`iconfont icon-${icon}`}
 92                                         style={`color:${color}`}
 93                                     />
 94                                     <span style={`color:${color}`}>{text}</span>
 95                                 </div>
 96                             );
 97                         }
 98                     }
 99                 ],
100                 // 表格内按钮配置
101                 tableBtnConfig: {
102                      245, //宽度
103                     update: true, // 编辑
104                     delete: true, // 删除
105                     expands: [
106                         {
107                             name: "查看报名",
108                             emitName: "checkRegistration",
109                             type: "primary"
110                         }
111                     ]
112                 },
113                 // 表格上方按钮配置
114                 topBtnConfig: [
115                     {
116                         title: "添加会员",
117                         icon: "el-icon-circle-plus"
118                     }
119                 ],
120                 // 筛选组件配置
121                 filterConfig: {
122                     filter_list: ["search", "year", "activation"],
123                     search_list: ["用户名", "昵称"]
124                 },
125                 // table的模态框表单配置,可配置表单类型,验证规则,是否必填,col-span布局可通过span参数配置
126                 formConfig: [
127                     {
128                         span: 24,
129                         label: "用户名",
130                         prop: "username",
131                         type: "text",
132                         rules: {
133                             required: true,
134                             validator: checkUserName,
135                             trigger: "blur"
136                         }
137                     },
138                     {
139                         span: 24,
140                         label: "昵称",
141                         prop: "nickname",
142                         type: "text",
143                         rules: {
144                             required: true,
145                             message: "请输入昵称",
146                             trigger: "blur"
147                         }
148                     },
149                     {
150                         span: 24,
151                         label: "密码",
152                         prop: "password",
153                         type: "password",
154                         rules: {
155                             required: true,
156                             validator: (rule, value, callback) => {
157                                 const is_edit = this.$refs.basetable.$refs
158                                     .dialogForm.isEdit; // 判断当前是编辑还是新增
159                                 const reg = /^[0-9a-zA-Z_]{6,15}$/; //6-15位数字字母下划线
160                                 if (!value) {
161                                     if (!is_edit) {
162                                         callback(new Error("密码不能为空"));
163                                     } else {
164                                         callback(); //可为空
165                                     }
166                                 } else if (reg.test(value) == false) {
167                                     callback(
168                                         new Error(
169                                             "密码必须为6~15位,英文与数字或下划线组合"
170                                         )
171                                     );
172                                 } else {
173                                     callback();
174                                 }
175                             },
176                             trigger: "blur"
177                         }
178                     },
179                     {
180                         span: 24,
181                         label: "确认密码",
182                         prop: "checkpassword",
183                         type: "password",
184                         rules: {
185                             required: true,
186                             validator: (rule, value, callback) => {
187                                 const psd = this.$refs.basetable.$refs
188                                     .dialogForm.formModel.password; // 输入的密码
189                                 const is_edit = this.$refs.basetable.$refs
190                                     .dialogForm.isEdit; // 判断当前是编辑还是新增
191                                 const reg = /^[0-9a-zA-Z_]{6,15}$/; //6-15位数字字母下划线
192                                 if (!value) {
193                                     if (!is_edit) {
194                                         callback(new Error("密码不能为空"));
195                                     } else {
196                                         callback(); //可为空
197                                     }
198                                 } else if (reg.test(value) == false) {
199                                     callback(
200                                         new Error(
201                                             "密码必须为6~15位,英文与数字或下划线组合"
202                                         )
203                                     );
204                                 } else if (value !== psd) {
205                                     callback(new Error("两次输入密码不一致!"));
206                                 } else {
207                                     callback();
208                                 }
209                             },
210                             trigger: "blur"
211                         }
212                     }
213                 ],
214                 // 表单基础数据类型,需要预先赋值
215                 formModel: {
216                     username: "",
217                     nickname: "",
218                     password: "",
219                     checkpassword: ""
220                 }
221             },
222             // ajax
223             table_ajax: theApi
224         };
225     },
226     components: { baseTable },
227     methods: {
228         checkRegistration: function(row = {}) {
229             this.$router.push({
230                 path: "/pages/index/enroll/entry/list",
231                 query: { id: row.id }
232             });
233         }
234     }
235 };
236 </script>
原文地址:https://www.cnblogs.com/chenzeyongjsj/p/10635977.html