When we do all kinds of background business, we are always unable to avoid various dialogs, and dialogs also need to add various forms, tables, and mixed with various operations, which are very annoying. Today, we will encapsulate a dialog with a nested base table. Where there is another dialog with a form, I will look back to it! No more words, first picture!!

Having encapsulated so many components together, we’ve learned how to encapsulate. Props, pass, operation, over. Look at the code

<template> <div> <el-dialog :title="title" :visible. Sync ="dialogVisible" :width="width" :center="isCenter" :fullscreen="isFull" > <! -- :before-close="handleClose" --> <! Here is the table component, < Custom-table :tableHeader="tableInfo. TableHeader "V-on ="$listeners" :tableData="tableInfo. TableData" :config="tableInfo.config" @getcheck="getcheck"> <template v-slot:handles="t"> <el-button-group> <el-link type="primary" @click="edit(t.col)" icon="el-icon-edit"> edit </el-link> <el-link type="danger" @click="deleteId(t.col)"> Delete < I class="el-icon-delete el-icon--right"></i> </el-link> </el-button-group> </template> </custom-table> <span slot="footer" Class ="dialog-footer"> <el-button @click="dialogVisible = false"> </el-button> <el-button :loading="vLoading" Type ="primary" @click="clickDialog"> confirm </el-button> </span> </el-dialog> </div> </template> <script> import CustomTable from '@/mycomponents/CustomTable/index.vue' export default { inheritAttrs:false, components:{ CustomTable }, // Sure button loading loading:{type:Boolean, default:false,}, // tableInfo:{type:Object, default:()=>{}}, Visible :{type:Boolean, default:false,}, // Popover title:{type:String, default:' title '}, IsCenter :{type:String, default:'50%'}, isCenter:{type:Boolean, default:false}, IsFull :{type:Boolean, default:false},}, data(){return {checkData:[],// table multiple select variable temp}}, // use.sync to implement multiple two-way binding. Here, change the dialog state using the computed property to avoid // violating the idea of a single data stream computed:{dialogVisible: {get() {return this.visible}, set(val) {this.$emit('update:visible', val)}}, // confirm button loading event vLoading: { get() { return this.loading }, set(val) { this.$emit('update:load', val) } } }, HandleClose (){this.$emit('beforeclose','close')} getCheck (val){this.checkData = val; }, // Click OK to close the popup and tell the parent component to do the clickDialog(){// Add loading state to the button, $emit('update:loading', true) this.$emit('handleconfirm', this.checkdata)}, Edit (t){this.$emit('toedit',t)}, // delete table, Notifies the parent to accept data deleteId(t){this.$emit('todelete',t)}}} </script>Copy the code

Note that the customTable component of the Dialog component is the same as the table component that we’ve wrapped up before, so we’ve added $Listeners to the table component and sent them the required event parameters. Let’s look at the table component

<template> <div> <el-table class="customer" :data="tableData" style="width: 100%" ref="customTable" @selection-change="tableSelectionChange"> <! <template v-for="(col,index) in tableHeader"> <template v-if="col.show"> <! <el-table-column v-if="col.type == 'selection'" :label="col.label" :type="col.type" :width="col.width"></el-table-column> <! <el-table-column v-else-if="col.type == 'index'" :label="col.label" :type="col.type" :width="col.width"></el-table-column> <el-table-column v-else-if="col.type == 'image'" :label="col.label" :width="col.width" :prop="col.prop"> <template slot-scope="scope"> <div class="content-image"><img :src="scope.row[col.prop]"/></div> </template> </el-table-column> <el-table-column v-else-if="col.type == 'date'" :label="col.label" :width="col.width" :min-prop="col.prop"> <template slot-scope="scope"> <i class="el-icon-time"></i> <span style="margin-left: 10px">{{ scope.row[col.prop] }}</span> </template> </el-table-column> <el-table-column v-else-if="col.type == 'handle'" :label="col.label" :min-width="col.width" :fixed="col.fixed"> <template slot-scope="scope"> <slot name="handles" :col="(scope)"></slot> </template> </el-table-column> <el-table-column v-else :label="col.label" :min-width="col.width" :prop="col.prop" :formatter="col.formatter? col.formatter:null"> </el-table-column> </template> </template> </el-table> <pagination v-show="config.total>0" :total="config.total" v-on="$listeners" :page.sync="config.searchList.page" :entry.sync="config.searchList.pageSize" /> </div> </template>Copy the code

So we can implement the basic popover table. Let’s look at our reference page

<template> <div class="pages-container"> <el-button type="primary" @click="openDoor" :title="dialogConfig.title" :visible.sync="dialogConfig.visible" :width="dialogConfig.width" :tableInfo="tableInfo" :loading.sync="dialogConfig.loading" @handleconfirm="confirm" @toedit="toEdit($event)" @todelete="toDelete($event)" @pagechange="getList" > </table-dialog> </div> </template> <script> import tableDialog from '@/mycomponents/Dialog/table.vue' import {tableHeader,tableData,config} from '@/utils/const.js' export default { Components :{tableDialog}, data(){return {dialogConfig:{width:'800px', title:' table popup title ', visible:false, loading:false, },// popup tableInfo:{tableHeader:tableHeader, tableData:tableData, config:config,}, Methods: {/ / open the popup window openDoor () {this. DialogConfig. Visible = true; }, / / sure business operations in the pop-up window, receiving data confirm (val) {the console. The log (' confirmation, choice of data, val) setTimeout (() = > {this. DialogConfig. Loading = false; ToEdit (e){console.log(' Table click edit ',e)}, // getList(e){console.log(' table click edit ', ToDelete (e){console.log(' table click delete, current row data ',e)}} </script>Copy the code

If you need to do something else in the table, you can do it by modifying the table component. If this small function is helpful to you, please click “like” big brother, thank you!!