首页 > 其他分享 >table表格 组件

table表格 组件

时间:2023-12-29 11:46:01浏览次数:25  
标签:el const 表格 return item import 组件 table row

 

<template>   <div>     <BaseTable       :searchConfig="searchConfig"       :operateBtnConfig="operateBtn"       :tableData="tableData"       :tableConfig="tableConfig"       :pagination="pagination"       :tableLoading="tableLoading"       @search="search"       @reset="reset"       @selectionChange="selectionChange"       @changePage="changePage"       @keyupEnterNative="fetchList"       @receiveSearch="receiveSearch"       ref="BaseTable"       idField="otherId"     >       <template v-slot:operate="{row}">         <el-link type="primary" size="medium" :underline="false" @click="editRow(row)" style="margin-right: 10px;">编辑</el-link>         <el-link type="danger" size="medium" :underline="false" @click="deleteData(row)">删除</el-link>       </template>     </BaseTable>
    <editForm       v-if="editVisible"       :visible="editVisible"       :editId="editId"       :companyList ="companyList"       :editType="editType"       @close="(type) => {type === 'reload' && this.fetchList();this.reloadCreators();editVisible = false}"     ></editForm>   </div> </template> <script> import { rules, searchConfig, tableConfig } from "./config"; import BaseTable from "@/components/BaseTable/index.vue" import baseMixins from "@/components/BaseTable/baseMixins" import editForm from "./components/editForm.vue" import { getCodingTypeList, getCreators ,} from "@/api/system/encodingRules" import{invoiceConfig ,invoiceConfigDelete} from "@/api/system/tickets" import { deepClone } from '@/utils'; import { getBranchCompany } from "@/api/shippingWorkOrder/index";
export default {   data() {     return {       rules: rules,       searchConfig: {},       tableConfig: tableConfig,       tableData: [],       editVisible: false,       editType: 'add',       editId: [],       typeOptions: [],       companyOptions: [],       creatorsList: [],       companyList:[],     };   },   mixins: [ baseMixins ],   components: { BaseTable, editForm },   computed: {     operateBtn: function() {       return [         {           name: '新增',           plain: false,           icon: 'el-icon-plus',           event: this.handleAdd         },         {           name: '删除',           type: 'danger',           icon: 'el-icon-delete',           event: this.deleteData         },       ]     },   },   created() {     this.fetchList()     Promise.allSettled([this.getBranchCompany(), this.getCodingTypeList(), this.getCreators()]).then(() => {       setTimeout(() => {         this.init()       }, 200)     })   },   methods: {     init() {       this.searchConfig = searchConfig({companyOptions: this.companyOptions, typeOptions: this.typeOptions, creatorsList: this.creatorsList})     },
    reloadCreators() {       Promise.allSettled([this.getCreators()]).then(() => {         this.init()       })     },
    // 录入人     async getCreators() {       let { code, data } = await getCreators();       if (code == 0) {         this.creatorsList = data.map(r => {return {value: r}});       }     },
    fetchList() {       const { pageNo , pageSize } = this.pagination       const {...rest } = this.searchForm       const data = {         pageNo,         pageSize,         ...rest       }       this.tableLoading = true       invoiceConfig(data).then(res => {         const { code, msg, data: { list, total } } = res
        if (code === 0) {           list.forEach((r, i) => {             r.monthLength = 2             r.dayLength = 2             r.otherId = new Date().getTime() + i           })           this.tableData = list;           this.$set(this.pagination, 'total', total)         } else {           this.tableData = []           msg && this.$message.warning(msg)         }       }).finally(() => {         this.tableLoading = false       })     },
    getCodingTypeList() {       getCodingTypeList().then(res => {         this.typeOptions = res.data       })     },
    getBranchCompany() {       getBranchCompany().then((res) => {         this.companyList = res.data;         this.companyOptions = deepClone(res.data.map(r => { return {...r, checked: false} }));       });     },
    // 新增     handleAdd() {       this.editVisible = false       this.editType = 'add'       this.editId = {}       setTimeout(() => {this.editVisible = true}, 100)     },
    // 编辑     editRow(row) {       this.editVisible = false       this.editId = row       this.editType = 'edit'       setTimeout(() => {this.editVisible = true}, 100)     },
    // 删除     deleteData(row) {       console.log(row);       let ids = []       if (row) {         ids.push(row.openInvoiceConfigId);       } else {         if (!this.getSelectRows()) return;                 ids = this.selectRows.map(r => r.openInvoiceConfigId)       }       console.log(ids);       this.$confirm(`确认删除该编码规则吗?`, '提示', {         confirmButtonText: '确定',         cancelButtonText: '取消',         type: 'warning'       }).then(() => {         invoiceConfigDelete(ids).then(res => {           const { code, data, msg} = res           if (code === 0 && data) {             this.$message.success(msg || '删除成功')             this.reloadCreators()             this.fetchList()           } else {             this.$message.warning(msg || '删除失败')           }         })       });     },   }, }; </script> <style scoped lang="scss"> </style> =============================================================================== 引入解释: config.js 配置   import { changeOptionsName } from '@/utils/utils' import { rulesItem } from '@/utils/constants'
export const searchConfig = ({ companyOptions, typeOptions, creatorsList }) => {
  return {     inline: true,     form: [       {         type: 'select',         name: 'deptId',         placeholder: '公司',         options: changeOptionsName(companyOptions, 'id', 'name') || [],       },             {         type: 'input',         name: 'taxNum',         placeholder: '企业税号',         options: creatorsList || [],       },     ]   } }
export const tableConfig = {   highlightCurrentRow: true,   fixedSelection: 'left',   columns: [     {       prop: 'deptName',       label: '公司名',       minWidth: 100     },     {       prop: 'taxNum',       label: '企业税号',     },     {       prop: 'appKey',       label: 'APP KEY',     },     {       prop: 'appSecret',       label: 'APP SECRET',     },     {       prop: 'token',       label: 'TOKEN',       minWidth: 80     },     {       prop: 'extensionNum',       label: '分机号',       minWidth: 80     },     {       prop: 'address',       label: '地址',       minWidth: 80     },     {       prop: 'phone',       label: '电话',       minWidth: 80     },     {       prop: 'payee',       label: '收款人',       minWidth: 110     },     {       prop: 'checker',       label: '复核人',       minWidth: 110     },     {       prop: 'drawer',       label: '开票人',       minWidth: 110     },     {       prop: 'creator',       label: '录入人',     },     {       prop: 'createTime',       label: '录入时间',       minWidth: 150     },     {       prop: 'updater',       label: '修改人',     },     {       prop: 'updateTime',       label: '修改时间',       minWidth: 150     },     {       prop: 'operate',       label: '操作',       fixed: 'right',       width: 96,       align: 'center',       headerAlign: 'center',       columShow: 'true',       slot: true     }   ] }
export const editRules = {   taxNum: rulesItem,   deptId:rulesItem,   appKey:rulesItem,   appSecret:rulesItem,   token:rulesItem,   extensionNum:rulesItem, }   searchConfig 中是搜索菜单中的搜索条件 tableConfig :  是配置tableb表格 tableConfig  ={ highlightCurrentRow :true  行高亮 fixedSelection: 'left',  左对齐 columns: [{}]  列参数 } editRules: 必填判断0 ========================================================================  编辑弹框: <template>   <BaseDialog :title="typeName[editType]" :visible.sync="visible" width="500px" @close="handleClose" @submit="submit" :loading="loading">     <el-form :model="form" :rules="editRules" ref="form" label-position="right">       <el-form-item label="公司名" prop="deptId">         <el-select v-model="form.deptId" filterable placeholder>           <el-option v-for="(item, index) in companyList" :key="index" :label="item.name" :value="item.id"></el-option>         </el-select>       </el-form-item>       <el-form-item label="企业税号" prop="taxNum">         <el-input v-model="form.taxNum" style="width: 194px;"></el-input>       </el-form-item>       <el-form-item label="APP_KEY" prop="appKey">         <el-input v-model="form.appKey" style="width: 194px;"></el-input>       </el-form-item>       <el-form-item label="APP_SECRET" prop="appSecret">         <el-input v-model="form.appSecret" style="width: 194px;"></el-input>       </el-form-item>       <el-form-item label="TOKEN" prop="token">         <el-input v-model="form.token" style="width: 194px;"></el-input>       </el-form-item>       <el-form-item label="分机号" prop="extensionNum">         <el-input v-model="form.extensionNum" style="width: 194px;"></el-input>       </el-form-item>       <el-form-item label="地址" prop="address">         <el-input v-model="form.address" style="width: 194px;" type="textarea" show-word-limit  maxlength="500" rows="5"></el-input>       </el-form-item>       <el-form-item label="电话" prop="phone">         <el-input v-model="form.phone" style="width: 194px;"></el-input>       </el-form-item>       <el-form-item label="收款人" prop="payee">         <el-select v-model="form.payee" filterable placeholder>           <el-option v-for="(item, index) in listPayee" :key="index" :label="item.username" :value="item.username" ></el-option>         </el-select>       </el-form-item>       <el-form-item label="复核人" prop="checker">          <el-select v-model="form.checker" filterable placeholder>           <el-option v-for="(item, index) in listChecker" :key="index" :label="item.username" :value="item.username" ></el-option>         </el-select>       </el-form-item>       <el-form-item label="开票人" prop="drawer">         <el-select v-model="form.drawer" filterable placeholder>           <el-option v-for="(item, index) in listDrawer" :key="index" :label="item.username" :value="item.username" ></el-option>         </el-select>       </el-form-item>     </el-form>   </BaseDialog> </template>
<script> import { editRules } from "../config";    //调用的必填项参数 import { invoiceConfigCreate,invoiceConfigUpdate,invoiceConfigGet } from "@/api/system/tickets";   //接口数据 import {getAssignUser} from "@/api/shippingWorkOrder/index"   //接口数据
export default {   props: {     editType: { // add edit copyAdd       type: String,       default: 'add'     },     visible: false,     editId: {       type: Object,       default: () => {}     },     companyList:{       type: Array,       default: () => []     }   },   data() {     return {       dialogVisible: this.visible,       typeName: {         add: '新增',         edit: '编辑',       },       typeOptions:[],       listDrawer:[],       listChecker:[],       listPayee:[],       form: {             },       editIdInfo:this.editId,       editRules: editRules,       loading: false,     };   },   created() {     this.getAssignUserList();     if(this.editType == 'edit'){       this.invoiceConfigGetList()     }   },   mounted() {   },   methods: {     handleClose(type) {       this.$emit('close', type)     },     // 提交     submit() {       this.$refs.form.validate((valid) => {         if (!valid) return false;         const data = {           ...this.form,         }         this.loading = true         if (this.editType != 'edit') {           this.handleRes(invoiceConfigCreate(data))         } else {           this.handleRes(invoiceConfigUpdate(data))         }       });     },     handleRes(_Promise) {       _Promise.then(res => {         const { code, msg } = res         this.$message.success(msg || this.editType == 'add' ? '新增成功' : '编辑成功')         this.handleClose('reload')       }).finally(() => this.loading = false)     },     getAssignUserList(){       getAssignUser().then((res)=>{         this.listDrawer = res.data;         this.listChecker = res.data;         this.listPayee = res.data;       })     },     invoiceConfigGetList(){       console.log(this.editIdInfo,"222");       let params={         id:this.editIdInfo.openInvoiceConfigId       }       invoiceConfigGet(params).then((res)=>{         this.form = {           ...res.data         }       })     }   } }; </script>
<style lang="scss" scoped> .el-form-item{   ::v-deep .el-form-item__label{     width: 100px !important;   }   ::v-deep .el-form-item__content{     .el-select{        width: 300px;     }     .el-input{       width: 300px !important;     }    .el-textarea{     width: 300px !important;    }   } } .title {   display: inline-block;   padding: 0px 5px;   color: var(--current-color);   font-size: 16px;   font-weight: 400;   margin-bottom: 7px;   margin-left: -5px; }
::v-deep .el-dialog__footer {   text-align: center; }
.flip-list-move {   transition: transform 0.5s; }
.no-move {   transition: transform 0s; } </style> ======================================================================= 引入的base tabe 文件夹  BaseTable 下的index.vue   <template>   <div class="container baseTable-container">     <!-- 搜索栏 -->     <div class="search search-box">       <template v-if="searchConfig.form && searchConfig.form.length">         <el-form ref="searchRef" :model="searchForm" :inline="searchConfig.inline" :label-width="searchConfig.labelWidth" @submit.native.prevent>           <el-form-item v-for="(item, index) in searchConfig.form" :label="item.label" :key="index" :prop="item.name">             <el-input v-if="item.type === 'input'" v-model="searchForm[item.name]" :style="item.style" :placeholder="item.placeholder" :clearable="item.clearable === false ? false : true"               :disabled="item.disabled" :readonly="item.readonly" @keyup.enter.native="keyupEnterNative" @dblclick.native="v => commonInputDblclick(v, item)" :suffix-icon="item.suffixIcon" :prefix-icon="item.prefixIcon" ></el-input>
            <el-input v-if="item.type === 'textarea'" type="textarea" v-model="searchForm[item.name]" :style="item.style" :placeholder="item.placeholder"               :clearable="item.clearable === false ? false : true" :disabled="item.disabled" :readonly="item.readonly" @keyup.enter.native="keyupEnterNative" @dblclick.native="v => commonInputDblclick(v, item)" :suffix-icon="item.suffixIcon" :prefix-icon="item.prefixIcon"></el-input>
            <el-input v-if="item.type === 'number'" type="number" v-model="searchForm[item.name]" :style="item.style" :placeholder="item.placeholder"               :clearable="item.clearable === false ? false : true" :disabled="item.disabled" :readonly="item.readonly" @keyup.enter.native="keyupEnterNative" @dblclick.native="v => commonInputDblclick(v, item)" :suffix-icon="item.suffixIcon" :prefix-icon="item.prefixIcon"></el-input>
            <el-date-picker               v-if="item.type === 'date'"               :type="item.datePickerType || 'daterange'"               :clearable="item.clearable === false ? false : true"               :disabled="item.disabled"               :style="item.style"               v-model="searchForm[item.name]"               :range-separator="item.rangeSeparator || '至'"               :start-placeholder="item.startPlaceholder || '开始时间'"               :end-placeholder="item.endPlaceholder || '结束时间'"               :value-format="item.valueFormat || (['daterange', 'data'].includes(item.datePickerType) ? 'yyyy-MM-dd' : ['datetimerange'].includes(item.datePickerType) ? 'yyyy-MM-dd HH:hh:mm' : 'yyyy-MM-dd')"               :default-time="item.defaultTime || (item.datePickerType === 'datetimerange' ? ['00:00:00', '23:59:59'] : null)"               :readonly="item.readonly"               @keyup.enter.native="keyupEnterNative"             ></el-date-picker>
            <el-time-select               v-if="item.type === 'timeSelect'"               v-model="searchForm[item.name]"               :disabled="item.disabled"               :clearable="item.clearable === false ? false : true"               :style="item.style"               :picker-options="item.pickerOptions"               :placeholder="item.placeholder"               :readonly="item.readonly"               @keyup.enter.native="keyupEnterNative">             </el-time-select>
            <el-time-picker               v-if="item.type === 'timePicker'"               :is-range="item.isRange"               :disabled="item.disabled"               :clearable="item.clearable === false ? false : true"               v-model="searchForm[item.name]"               :style="item.style"               :picker-options="item.pickerOptions"               :range-separator="item.rangeSeparator || '至'"               :start-placeholder="item.startPlaceholder || '开始时间'"               :end-placeholder="item.endPlaceholder || '结束时间'"               :placeholder="item.placeholder"               :readonly="item.readonly"               @keyup.enter.native="keyupEnterNative">             </el-time-picker>
            <el-select v-if="item.type === 'select'" v-model="searchForm[item.name]" :style="item.style" :placeholder="item.placeholder" :clearable="item.clearable === false ? false : true" filterable               :disabled="item.disabled" :readonly="item.readonly" @keyup.enter.native="keyupEnterNative" @change="v => {commonSelectChange(v, item)}">               <template v-if="typeof(item.renderOption) === 'function'">                 <el-option v-for="(selectItem, selectIndex) in item.options" :key="selectIndex" :label="item.renderOption(selectItem)" :value="selectItem.value">                   {{ item.renderOption(selectItem) }}                 </el-option>               </template>               <template v-else>                 <el-option v-for="(selectItem, selectIndex) in item.options" :key="selectIndex" :label="selectItem.label" :value="selectItem.value"></el-option>               </template>             </el-select>
            <template v-if="item.type === 'selectGroup'">               <el-col :span="11">                 <el-select v-model="searchForm[item.list[0].name]" :style="item.list[0].style" :clearable="item.list[0].clearable === false ? false : true" :placeholder="item.list[0].placeholder || ''">                   <el-option v-for="(selectItem, selectIndex) in item.list[0].options" :key="selectIndex" :label="selectItem.label" :value="selectItem.value"></el-option>                 </el-select>               </el-col>               <el-col style="text-align: center;" :span="2">—</el-col>               <el-col :span="11">                 <el-select v-model="searchForm[item.list[1].name]" :style="item.list[1].style" :clearable="item.list[1].clearable === false ? false : true" :placeholder="item.list[1].placeholder || ''">                   <el-option v-for="(selectItem, selectIndex) in item.list[1].options" :key="selectIndex" :label="selectItem.label" :value="selectItem.value"></el-option>                 </el-select>               </el-col>             </template>
            <template v-if="item.type === 'inputGroup'">               <el-col :span="11">                 <el-input v-model="searchForm[item.list[0].name]" :type="item.list[0].type" :style="item.list[0].style" :placeholder="item.list[0].placeholder || ''" :clearable="item.list[0].clearable === false ? false : true"                   :disabled="item.list[0].disabled" :readonly="item.list[0].readonly" @keyup.enter.native="keyupEnterNative" ></el-input>               </el-col>               <el-col style="text-align: center;" :span="2">—</el-col>               <el-col :span="11">                 <el-input v-model="searchForm[item.list[1].name]" :type="item.list[0].type" :style="item.list[1].style" :placeholder="item.list[1].placeholder || ''" :clearable="item.list[1].clearable === false ? false : true"                   :disabled="item.list[1].disabled" :readonly="item.list[1].readonly" @keyup.enter.native="keyupEnterNative" ></el-input>               </el-col>             </template>
            <v-selectpage v-if="item.type === 'selectPage'" :style="item.style" :ref="`selectPage_${item.name}`" v-model="searchForm[item.name]" :data="item.options" :key-field="item.keyField"               :result-format="item.resultFormat || resultFormat"               :show-field="item.showField"               :search-field="item.searchField || 'searchField'"               :params="item.searchParams"               :multiple="item.multiple"               :clearable="item.clearable === false ? false : true"               :disabled="item.disabled"               :tb-columns="item.tbColumns || defaultSelectPageColumns" :placeholder="item.placeholder || ' '">             </v-selectpage>
            <base-selectPage v-if="item.type === 'baseSelectPage'" :style="item.style" v-model="searchForm[item.name]" :data="item.options" :keyField="item.keyField"               :showField="item.showField"               :searchField="item.searchField || 'keyword'"               :concatField="item.concatField"               :defaultRow="item.defaultRow || {}"               :searchParams="item.searchParams"               :multiple="item.multiple"               :tb-columns="item.tbColumns || defaultSelectPageColumns"               :disabled="item.disabled"               :clearable="item.clearable === false ? false : true"               :placeholder="item.placeholder || ''"               @change="v => {commonSelectChange(v, item)}">             </base-selectPage>
            <el-cascader v-if="item.type === 'cascader'" v-model="searchForm[item.name]" :clearable="item.clearable === false ? false : true" :options="item.options" :style="item.style" :placeholder="item.placeholder" :disabled="item.disabled" :readonly="item.readonly"></el-cascader>
            <treeselect v-if="item.type === 'treeselect'" v-model="searchForm[item.name]" :options="item.options" :normalizer="typeof(item.normalizer) === 'function' ? item.normalizer : normalizer" :show-count="item.showCount === false ? false : true"               :placeholder="item.placeholder"               :disabled="item.disabled"               :multiple="item.multiple"               :clearable="item.clearable === false ? false : true"/>
            <template v-if="item.type === 'slot'">               <slot :name="item.name" :form="searchForm"></slot>             </template>           </el-form-item>
          <!-- 三种布局类型 last / bottom / more -->           <el-form-item v-if="!searchConfig.layoutType || searchConfig.layoutType === 'last'">             <el-button type="primary" @click="search">查 询</el-button>             <el-button @click="reset" v-if="searchConfig.showResetBtn === false ? false : true">重 置</el-button>           </el-form-item>         </el-form>         <div v-if="searchConfig.layoutType === 'bottom'" class="searchBtn">           <el-button type="primary" @click="search">查 询</el-button>           <el-button @click="reset" v-if="searchConfig.showResetBtn === false ? false : true">重 置</el-button>         </div>       </template>       <template v-else>         <p class="search-loading"><i class="el-icon-loading"></i> 加载中...</p>       </template>     </div>
    <div class="line"></div>
    <!-- 操作栏 -->     <div class="operateBtn btn-box" v-if="operateBtnConfig.length">       <div class="operateBtn-left">         <!-- formcreate 循环按钮使用自定义组件 -->         <BaseBtnList :list="operateBtnConfig"></BaseBtnList>       </div>
      <div class="operateBtn-right">         <slot name="operateBtnRight"></slot>       </div>     </div>
    <!-- Table栏 -->     <div class="baseTable" v-if="tableConfig.showTable === false ? false : true">       <el-table         v-if="!tableConfig.isVirtualTable"         ref="table"         class="tableMaxHeightClass"         v-loading="tableLoading"         :data="tableData"         :tooltip-effect="tableConfig.tooltipEffect || 'dark'"         style="width: 100%"         :border="tableConfig.border === false ? false : true"         :highlight-current-row="tableConfig.highlightCurrentRow"         :current-row-key="tableConfig.currentRowKey || 'id'"         :row-key="tableConfig.rowKey"         :max-height="tableMaxHeight"         :row-class-name="toString.call(tableConfig.rowClassName) ===  '[object Undefined]' && idField ? defaultRowClassName : tableConfig.rowClassName"         :cell-class-name="tableConfig.cellClassName"         :header-row-class-name="tableConfig.headerRowClassName"         :header-cell-class-name="tableConfig.headerCellClassName"         :span-method="({row, column, rowIndex, columnIndex}) => toString.call(tableConfig.spanMethod) ===  '[object Undefined]' ? () => {} : tableConfig.spanMethod({row, column, rowIndex, columnIndex, tableRef: $refs.table})"         @select="select"         @select-all="selectAll"         @selection-change="selectionChange"         @row-dblclick="rowDblclick"         @row-click="rowClick"         @cell-click="cellClick"         @row-contextmenu="rowContextmenu"         @header-dragend="headerDragend"         @sort-change="sortChange">         <el-table-column           type="expand"           v-if="tableConfig.showExpand"           align="center"           width="55">           <template slot-scope="props">             <slot name="expand" :props="props" :row="props.row"></slot>           </template>         </el-table-column>
        <el-table-column           type="selection"           v-if="tableConfig.showSelection === false ? false : true"           :reserve-selection="tableConfig.reserveSelection === true ? true : false"           :fixed="tableConfig.fixedSelection"           :selectable="tableConfig.selectable"           align="center"           width="44">         </el-table-column>
        <el-table-column           type="index"           v-if="tableConfig.showIndex === false ? false : true"           align="center"           label="序号"           width="56">         </el-table-column>
        <template v-for="(item, index) in tableConfig.columns">           <el-table-column             v-if="(item.columShow === 'false' || item.columShow === false) ? false : true"             :key="index"             :width="item.width"             :min-width="item.minWidth || 120"             :prop="item.prop"             :label="item.label"             :fixed="item.fixed"             :sortable="item.sortable === false ? false : true"             :render-header="item.renderHeader"             :align="item.align || 'left'"             :header-align="item.headerAlign || 'left'"             :class-name="item.className"             :sort-method="item.sortMethod"             :show-overflow-tooltip="item.showOverflowTooltip === false ? false : true">             <template slot-scope="scope" v-if="!item.formatter">                 <slot v-if="item.slot" :name="item.prop" :scope="scope" :index="scope.$index" :row="scope.row"></slot>                 <span v-else>{{ scope.row[item.prop] }}</span>             </template>
            <!-- 合并单元格 传children -->             <template v-if="item.children">               <el-table-column                 v-for="(childItem, childIndex) in item.children"                 :key="childIndex"                 :label="childItem.label"                 :prop="childItem.prop"                 :width="childItem.width"                 :min-width="childItem.minWidth || 100"                 :align="childItem.align || 'left'"                 :header-align="childItem.headerAlign || 'left'"                 :class-name="childItem.className"                 show-overflow-tooltip                 :sortable="item.sortable === false ? false : true"                 :sort-method="item.sortMethod"               >                 <template slot-scope="scope">                     <slot v-if="childItem.slot" :name="childItem.prop" :scope="scope" :index="scope.$index" :row="scope.row"></slot>                     <span v-else>{{ scope.row[childItem.prop] ? scope.row[childItem.prop] : childItem.empty }}</span>                 </template>               </el-table-column>             </template>           </el-table-column>         </template>       </el-table>
      <!-- 虚拟表格 -->       <u-table         v-else         ref="table"         class="tableMaxHeightClass"         v-loading="tableLoading"         :data="tableData"         :tooltip-effect="tableConfig.tooltipEffect || 'dark'"         style="width: 100%"         :border="tableConfig.border === false ? false : true"         :highlight-current-row="tableConfig.highlightCurrentRow"         :current-row-key="tableConfig.currentRowKey || 'id'"         :max-height="tableConfig.tableMaxHeight || tableMaxHeight"         :row-class-name="toString.call(tableConfig.rowClassName) ===  '[object Undefined]' && idField ? defaultRowClassName : tableConfig.rowClassName"         :cell-class-name="tableConfig.cellClassName"         :header-row-class-name="tableConfig.headerRowClassName"         :header-cell-class-name="tableConfig.headerCellClassName"         :span-method="({row, column, rowIndex, columnIndex}) => toString.call(tableConfig.spanMethod) ===  '[object Undefined]' ? () => {} : tableConfig.spanMethod({row, column, rowIndex, columnIndex, tableRef: $refs.table})"         @select="select"         @select-all="selectAll"         @selection-change="selectionChange"         @row-dblclick="rowDblclick"         @row-click="rowClick"         @cell-click="cellClick"         @row-contextmenu="rowContextmenu"         @header-dragend="headerDragend"         @sort-change="sortChange"         use-virtual         :row-height="tableConfig.rowHeight || uTableRowHeight"         >         <u-table-column           type="expand"           v-if="tableConfig.showExpand"           align="center"           width="56">           <template slot-scope="props">             <slot name="expand" :props="props" :row="props.row"></slot>           </template>         </u-table-column>
        <u-table-column           type="selection"           v-if="tableConfig.showSelection === false ? false : true"           :fixed="tableConfig.fixedSelection"           :selectable="tableConfig.selectable"           align="center"           header-align="center"           width="40">         </u-table-column>
        <!-- 有些需要在序号前加东西 -->         <u-table-column           v-if="tableConfig.showOther"           align="center"           width="56">           <template slot-scope="scope">             <slot name="showOther" :scope="scope" :index="scope.$index" :row="scope.row"></slot>           </template>         </u-table-column>
        <u-table-column           type="index"           v-if="tableConfig.showIndex === false ? false : true"           align="center"           label="序号"           class-name="uIndex"           width="56">         </u-table-column>
        <template v-for="(item, index) in tableConfig.columns">           <u-table-column             v-if="(item.columShow === 'false' || item.columShow === false) ? false : true"             :key="index"             :width="item.width"             :min-width="item.minWidth || 120"             :prop="item.prop"             :label="item.label"             :fixed="item.fixed"             :sortable="item.sortable === false ? false : true"             :render-header="item.renderHeader"             :align="item.align || 'left'"             :header-align="item.headerAlign || 'left'"             :class-name="item.className"             :sort-method="item.sortMethod"             :show-overflow-tooltip="item.showOverflowTooltip === false ? false : true">             <template slot-scope="scope" v-if="!item.formatter">                 <slot v-if="item.slot" :name="item.prop" :scope="scope" :index="scope.$index" :row="scope.row"></slot>                 <span v-else>{{ scope.row[item.prop] }}</span>             </template>
            <!-- 合并单元格 传children -->             <template v-if="item.children">               <u-table-column                 v-for="(childItem, childIndex) in item.children"                 :key="childIndex"                 :label="childItem.label"                 :prop="childItem.prop"                 :width="childItem.width"                 :min-width="childItem.minWidth || 100"                 :align="childItem.align || 'left'"                 :header-align="childItem.headerAlign || 'left'"                 :class-name="childItem.className"                 show-overflow-tooltip                 :sortable="item.sortable === false ? false : true"                 :sort-method="item.sortMethod"               >                 <template slot-scope="scope">                     <slot v-if="childItem.slot" :name="childItem.prop" :scope="scope" :index="scope.$index" :row="scope.row"></slot>                     <span v-else>{{ scope.row[childItem.prop] ? scope.row[childItem.prop] : childItem.empty }}</span>                 </template>               </u-table-column>             </template>           </u-table-column>         </template>       </u-table>
      <div class="pagination" v-if="tableConfig.showPagination === false ? false : true">         <el-pagination           background           @size-change="val => handlePageChange(val, 'pageSize')"           @current-change="val => handlePageChange(val, 'pageNo')"           :current-page="basePagination.pageNo"           :page-sizes="basePagination.pageSizes"           :page-size="basePagination.pageSize"           :pager-count="pagerCount"           :layout="pagerCount === 7 ? 'total, sizes, prev, pager, next, jumper' : 'total, pager'"           :total="basePagination.total">         </el-pagination>       </div>     </div>   </div> </template>
<script> import tableConfigMixins from "@/views/mixin/tableConfigMixins" import { defaultSelectPageColumns } from "@/utils/constants"; import { resetSelectPage } from "@/utils/utils"; import { deepClone } from '@/utils';
import treeselect from "@riophae/vue-treeselect"; import "@riophae/vue-treeselect/dist/vue-treeselect.css";
import BaseBtnList from '@/components/BaseBtnList/index.vue'
export default {   name: 'BaseTable',   props: {     // 搜索栏配置     searchConfig: {       type: Object,       default: () => {         return {           inline: true,           layoutType: 'last',           form: [             {               // type: 'input',               // name: 'name',               // label: '活动名称',               // placeholder: '活动名称'             }           ]         }       }     },     // 操作栏配置     operateBtnConfig: {       type: Array,       default: () => {         return []       }     },     // table数据     tableData: {       type: Array,       default: () => {         return []       }     },     // table栏配置     tableConfig: {       showTable: true,       showSelection: true,       isVirtualTable: false,  // 是否虚拟表格       columns: [         {           prop: '',           label: '',           minWidth: ''         }       ]     },     tableLoading: false,     // 分页配置     pagination: {       type: Object,       default: () => {         return {           pageNo: 1,           total: 0,           pageSize: 30,           pageSizes: [ 30, 100, 500, 1000 ]         }       }     },     // table的唯一id字段, 用做默认row-class-name使用     idField: String   },   components: {treeselect, BaseBtnList},   data() {     return {       // 选中的数据       selectRows: [],       // 表单       searchForm: {},       // 分页       basePagination: this.pagination,       // 分页组件的默认table配置       defaultSelectPageColumns: defaultSelectPageColumns,       uTableRowHeight: 30,       pagerCount: document.body.clientWidth < 992 ? 5 : 7     }   },   mixins: [ tableConfigMixins ],   created() {   },   mounted() {     this.searchConfig?.form?.forEach(r => {       if (r.defaultValue != null) {         this.$nextTick(() => {           this.$set(this.searchForm, r.name, r.defaultValue)         })       }     })   },   methods: {     select(rows, row) {       this.$emit('select', rows, row)     },     selectAll(rows) {       this.$emit('selectAll', rows)     },     selectionChange(rows) {       this.selectRows = rows       this.$emit('selectionChange', rows)     },     search() {       let obj = deepClone(this.searchForm)       let searchForm = {}       for (const key in obj) {         if (key != 'undefined') {           searchForm[key] = obj[key]         }       }       this.$emit('search', searchForm)     },     reset() {       this.$refs.searchRef.resetFields()
      this.searchConfig.form.forEach(r => {         if (r.type === 'selectPage') {           resetSelectPage(`selectPage_${r.name}`, this)         }       })
      this.searchForm = {}
      this.$nextTick(() => {         this.searchConfig?.form?.forEach(r => {           if (r.defaultValue != null) {               this.$set(this.searchForm, r.name, r.type === 'selectPage' ?               String(typeof(r.defaultValue) === 'function' ? r.defaultValue()               :               r.defaultValue) : typeof(r.defaultValue) === 'function' ? r.defaultValue() : r.defaultValue)           }         })         // 重置数据         let obj = deepClone(this.searchForm)         let searchForm = {}         for (const key in obj) {           if (key != 'undefined') {             searchForm[key] = obj[key]           }         }         this.$emit('reset', searchForm)       })     },     handlePageChange(val, type) {       this.$set(this.basePagination, type, val)       type === 'pageSize' && (this.$set(this.basePagination, 'pageNo', 1))       this.$emit('changePage', this.basePagination)     },     rowDblclick(row, column, event) {       this.$emit('rowDblclick', row, column, event)     },     rowClick(row, column, event) {       this.$emit('rowClick', row, column, event)     },     cellClick(row, column, cell, event) {       this.$emit('cellClick', row, column, cell, event)     },     rowContextmenu(row, column, event) {       this.$emit('rowContextmenu', row, column, event)     },     // 设置默认值     setDefaultValue() {       this.searchConfig?.form?.forEach(r => {         if (r.defaultValue != null) {           this.$set(this.searchForm, r.name, r.type === 'selectPage' ?           String(typeof(r.defaultValue) === 'function' ? r.defaultValue()           :           r.defaultValue) : typeof(r.defaultValue) === 'function' ? r.defaultValue() : r.defaultValue)         }       })     },     resultFormat(res) {       const {list, total} = res.data       return {list, totalRow: total}     },     // 输入框触发enter事件     keyupEnterNative() {       this.$emit('keyupEnterNative')     },     // 列宽拖拽     headerDragend(newWidth, oldWidth, column, event) {       this.$emit('headerDragend', newWidth, oldWidth, column, event)     },     // 设置勾选时默认的rowClassName     defaultRowClassName({row}) {       const isSelect = this.selectRows.some(r => r[this.idField] === row[this.idField])       if (isSelect) return'select-row'     },     commonSelectChange(v, item) {       toString.call(item.change) === '[object Function]' ? item.change(v) : null     },     commonInputDblclick(v, item) {       toString.call(item.dblclick) === '[object Function]' ? item.dblclick(v) : null     },     // 转换tree数据结构     normalizer(node) {       if (node.children && !node.children.length) {         delete node.children;       }       return {         id: node.id,         label: node.name,         children: node.children       };     },     sortChange({ column, prop, order }) {       this.$emit('sortChange', {column, prop, order, tableData: this.$refs?.table?.tableData})     }   },   watch: {     'searchConfig': function() {       this.setDefaultValue()     },     'pagination': {       handler(n, o) {         this.basePagination = n       },       deep: true     },     tableData: function(n) {       if (n.length && this.tableConfig.isVirtualTable) {         this.$nextTick(() => {           this.uTableRowHeight = document.querySelectorAll('.uIndex')?.[1]?.getBoundingClientRect()?.height || 30         })       }     },     'searchForm': {       handler(n, o) {         this.$emit('receiveSearch', n)       },       deep: true     },   } } </script>
<style lang="scss" scoped> .container {   padding: 0 0 20px;   min-height: calc(100vh - 94px);   width: calc(100% - 20px);   margin: 0 auto;   margin-top: 10px;     border-radius: 4px; } .line {   width: 100%;   height: 10px;   } .search, .operateBtn, .baseTable{   } .search {   padding: 17px 20px 7px;   border-radius: 4px;   .search-loading {     padding-bottom: 20px;     font-size: 15px;   }   ::v-deep .el-form-item{     margin-bottom: 10px;     margin-top: 0;   }   ::v-deep .el-button--small {     transform: translateY(-1px);   } } .operateBtn {   padding: 16px 20px 6px;   border-top-left-radius: 4px;   border-top-right-radius: 4px;   display: flex;   justify-content: space-between;   align-items: center;   ::v-deep .iconfont {     font-size: 12px;     margin-right: 5px;   }   .operateBtn-left {     ::v-deep .el-button{       margin-left: 0;       margin-right: 10px;       margin-bottom: 10px;     }   }   .operateBtn-right {     max-width: 40%;   } } .baseTable {   padding: 0 20px 15px;   border-bottom-left-radius: 4px;   border-bottom-right-radius: 4px; }
.searchBtn {   text-align: center;   padding: 0 0 20px; }
.pagination {   text-align: right;   padding-top: 15px; }
@media screen and (max-width: 1366px) {   ::v-deep .el-select, ::v-deep .el-input {     max-width: 120px;   }   ::v-deep .el-date-editor--daterange.el-input, ::v-deep .el-date-editor--daterange.el-input__inner, ::v-deep .el-date-editor--timerange.el-input, ::v-deep .el-date-editor--timerange.el-input__inner {     width: 220px;   }   ::v-deep .el-form-item__label {     vertical-align: super !important;   }   .el-form-item {     margin-bottom: 10px !important;     margin-right: 10px !important;   }   .search .el-form-item.el-form-item--small .v-selectpage {     width: 120px;   }   .search .el-form-item.el-form-item--mini .v-selectpage div.sp-input-container div.sp-base{     width: 120px;   }   .pagination {     max-width: 95%;   } } </style>   baseTable 文件夹下的  baseMixins.js import baseFetchOptions from "@/views/mixin/baseFetchOptions" import { deepClone } from "@/utils/index";
export default {   data() {     return {       tableLoading: false,       searchForm: {},       tableData: [],       selectRows: [],       pagination: {         pageNo: 1,         total: 0,         pageSize: 30,         pageSizes: [ 30, 100, 500, 1000 ]       }     }   },   mixins: [ baseFetchOptions ],   created() {   },   methods: {     // 默认的请求列表函数     fetchList() {},     // 搜索     search(form) {       this.searchForm = form       this.fetchList()     },     // 接收改变的searchForm     receiveSearch(form) {       this.searchForm = form     },     // 重置     reset(form) {       this.searchForm = form       this.pagination.pageNo = 1       this.fetchList()     },     // 选中行     selectionChange(rows) {       this.selectRows = rows     },     // 分页事件     changePage(pageCnfig) {       this.pagination = deepClone(pageCnfig)       this.fetchList()     },     // 限制多选     getSelectRows() {       const { length } = this.selectRows       if (!length) {         this.$message.warning("至少选择一条数据!")         return false       }       return true     },     // 限制单选     getSelectRow() {       const { length } = this.selectRows       if (length != 1) {         this.$message.warning("请选择一条数据!")         return false       }       return true     }   } } =============================================================== baseTable 下的index 引入的  tableConfigMixins   tableConfigMixins:    // 此mixins用做处理所有table max height import { debounce } from 'throttle-debounce' export default {   data() {     return {       tableMaxHeight: localStorage.getItem('tableMaxHeight') || 1000,       otherHeight: 0, // 防止有别的高度没计算到     }   },   computed: {   },   created() {   },   mounted() {     this.setTableMaxHeight()
    window.onresize = debounce(200, () => {       this.setTableMaxHeight()     })   },   methods: {     setTableMaxHeight() {       this.$nextTick(() => {         setTimeout(() => {           const { height } = document.body.getBoundingClientRect()           const { height: navHeight } = document.querySelector('.navbar').parentElement.getBoundingClientRect()           const { height: tableHeaderHeight, top: tableHeaderMarginTop } = document.querySelector('.el-table__header-wrapper').getBoundingClientRect()
          // 使用属性控制           const h1 = height - 30 - tableHeaderHeight - tableHeaderMarginTop - this.otherHeight           this.tableMaxHeight = h1 < 450 ? 450 : h1
          // 使用class和属性控制           if (document.querySelector('.el-table.tableMaxHeightClass')) {             const { height: searchH } = document.querySelector('.search-box')?.getBoundingClientRect() || {height: 0}             const { height: btnH } = document.querySelector('.btn-box')?.getBoundingClientRect() || {height: 0}             const { height: paginationH } = document.querySelector('.pagination')?.getBoundingClientRect() || {}             const h = (height - navHeight - searchH - btnH - paginationH - 80 - this.otherHeight)             const _h =  h < 450 ? 450 : h             document.querySelector('.el-table.tableMaxHeightClass').style.maxHeight = _h + 'px'             this.tableMaxHeight = _h           }           // 使用class和属性控制, 虚拟 table 使用           if (document.querySelector('.tableMaxHeightClass')?.querySelector('.el-table')) {             const { height: searchH } = document.querySelector('.search-box')?.getBoundingClientRect()             const { height: btnH } = document.querySelector('.btn-box')?.getBoundingClientRect()             const { height: paginationH } = document.querySelector('.pagination')?.getBoundingClientRect() || {}             const h = (height - navHeight - searchH - btnH - paginationH - 80 - this.otherHeight)             const _h =  h < 450 ? 450 : h             document.querySelector('.tableMaxHeightClass').querySelector('.el-table').style.maxHeight = _h + 'px'             this.tableMaxHeight = _h           }         },500)       })     }   }, } ==================================================================================== import { defaultSelectPageColumns } from "@/utils/constants";   defaultSelectPageColumns :   // 基础分页下拉Columns export const defaultSelectPageColumns = [   { title: 'CODE', data: 'code', width: 130 },   { title: '中文名', data: 'nameCn', minWidth: 180 },   { title: '英文名', data: 'nameEn', minWidth: 250  }, ] ==================================================================================== import { resetSelectPage } from "@/utils/utils";   resetSelectPage : /**  * 清除selectPage选中项  * @param {*} name  * @param {*} $vm vue实例  */ export function resetSelectPage (name, $vm) {   const el = toString.call($vm.$refs[name]) === '[object Array]' ? $vm.$refs[name][0] : $vm.$refs[name]   el?.remove?.()
  // 处理重置后多选selectPage会展开下拉框问题   setTimeout(() => {     el?.close?.()   }) } ============================================================================================ import { deepClone } from '@/utils';   // 深拷贝对象 // https://github.com/JakHuang/form-generator/blob/dev/src/utils/index.js#L107 export function deepClone(obj) {   const _toString = Object.prototype.toString
  // null, undefined, non-object, function   if (!obj || typeof obj !== 'object') {     return obj   }
  // DOM Node   if (obj.nodeType && 'cloneNode' in obj) {     return obj.cloneNode(true)   }
  // Date   if (_toString.call(obj) === '[object Date]') {     return new Date(obj.getTime())   }
  // RegExp   if (_toString.call(obj) === '[object RegExp]') {     const flags = []     if (obj.global) { flags.push('g') }     if (obj.multiline) { flags.push('m') }     if (obj.ignoreCase) { flags.push('i') }
    return new RegExp(obj.source, flags.join(''))   }
  const result = Array.isArray(obj) ? [] : obj.constructor ? new obj.constructor() : {}
  for (const key in obj) {     result[key] = deepClone(obj[key])   }
  return result }   ==================================================================== import BaseBtnList from '@/components/BaseBtnList/index.vue'   BaseBtnList : <template>   <div>     <template v-for="(item, index) in list">       <el-button         :type="item.type || 'primary'"         :icon="typeof item.icon != 'function' ? item.icon : null"         :key="index"         :plain="item.plain === false ? false : true"         :loading="item.loading === true ? true : false"         :style="item.style"         :class="item.class"         :disabled="item.disabled"         @click="item.event()"         v-if="item.show === false ? false : true"         >{{ item.name }}</el-button       >     </template>   </div> </template>
<script> export default {   props: {     list: {       type: Array,       default: () => [],     },   },   data() {     return {
    };   },   created() {},   methods: {   }, }; </script> <style scoped lang="scss"> ::v-deep .el-button+.el-button {   margin-bottom: 10px; } </style> ================================================================= import treeselect from "@riophae/vue-treeselect"; import "@riophae/vue-treeselect/dist/vue-treeselect.css";  此引入需要安装插件 安装的命令如下,哪里需要哪里引入,同时使用的components中也需要在页面中使用 yarn  add @riophae/vue-treeselect  

标签:el,const,表格,return,item,import,组件,table,row
From: https://www.cnblogs.com/rockyjs/p/17934502.html

相关文章

  • 下拉分页组件 select-page
    组件使用文档:https://terryz.gitee.io/vue/#/selectpage/demo实例:需要使用的下拉分页的页面: <el-form-itemlabel="公司"prop="carrierId">     <base-selectPagev-model="ruleForm.carrierId"keyField="crmCorporationId"@ch......
  • vue 将百度地图或者高德地图组件化
    一、前言百度地图已经有了react相关的组件库,本人用的百度地图v3.0和vue3我仅仅是抛砖引玉,百度地图webgl、高德地图都是一样的,因为底层都是通过js控制地图如果用组件的方式开发,比如我将BMap.Marker作为一个组件,我暴露一个参数position,其目的是控制BMap.Marker位置......
  • Layui treeTable 使用【数据不显示、子级不显示】
    //返回JSON数据类publicclassLeaveMessageTreeTable{publicLeaveMessageTreeTable(){this.children=newList<LeaveMessageTreeTable>();this.isParent=false;}publicintId{get;set;}publicintUserId{get;s......
  • 【泰裤辣 の Unity百宝箱】Canvas组件四件套讲解
    【泰裤辣のUnity百宝箱】Canvas组件四件套讲解原创 打工人小棋 打工人小棋 2023-05-1613:24 发表于广东1.介绍在上一期内容中,我分享了一套简单易用的UI框架。没想到大家的学习热情这么高,讨论度是目前所有内容最高的。由此可见,天下苦UI(秦)久已!!!接下去,我们继续......
  • CompletableFuture异步编程
    一、基本介绍1.1 多线程编程的发展过程创建线程的方式继承 Thread 类实现 Runnable 接口特点:没有参数,没有返回值,没办法抛出异常JDK 1.5 进阶版Callable + FutureCallable接口中定义的 V call() throws Exception,该方法可以返回泛型值 V,并能够抛出异常......
  • Unity_U_OP1 ScriptableObject 替代单例
    核心思想:解耦GameManager单例模式,不再由一个单例管理所有事件触发,拆分成无数个小单例,各自管理优点:更加灵活的事件管理模式复用性高,对于相关类型的事件,只需要写一遍代码,剩下的拖拖拖就可以实现相同的功能。缺点:管理起来相对麻烦不利于维护,除非对这个系统非常了解,要不然排......
  • 使用hook封装表格常用功能(react)
    实现内容配置分页:usePagination生成过滤项:useFilter获取表格选择配置:useSelect生成批量删除按钮:useDelete生成模态框:useModal示例render部分:<React.Fragment><Formlayout="inline">{DeleteEle}{FilterEles}</Form><Table{...{......
  • nftables语法及例子
    nftables语法及例子来源  https://www.cnblogs.com/mind-water/articles/10789606.html 参考 https://wiki.nftables.org/wiki-nftables/index.php/Quick_reference-nftables_in_10_minutes 先上我自己实际测试通过的例子,用例子便于在实践中学习:#0---说明---下面......
  • C++ Qt开发:SqlTableModel映射组件应用
    Qt是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍SqlTableModule组件的常用方法及灵活运用。在多数情况下我们需要使用SQL的方法来维护数据库,但此......
  • 封装一个表情包组件(支持自定义表情图片)(基于vue3语法)
    效果图文件图直接贴代码emotion.vue<template><divclass="emotion-containerbeauty-scroll-livechat"><divclass="emotion-btn"@click="toggleEmotionShow"><spanclass="iconfonticon-biaoqing1&quo......