vue element table二次封装,可行内编辑

347 阅读1分钟

随便封装玩玩,目前可支持日期控件、文本框、输入框,可动态配置按钮...

不多说了,先上图看效果

snipaste_20211104_171512.png 父组件调用:

<table-list
      :table-column-list="config.tableColumnList"
      :table-data="tableData"
      :action-list="config.actionList"
      :action-width="config.actionWidth"
      :is-show-selection="config.isShowSelection"
      @handleSelectionChange="handleSelectionChange"
      @handleCurrentChange="handleCurrentChange"
      @add="addEvent"
      @edit="editEvent"
    />

配置js文件

export default {
  isShowSelection: true,
  actionWidth: '160',
  tableColumnList: [
    {
      prop: 'date',
      label: '日期',
      type: 'time',
      disabled: false,
      isEdit: false,
      width: 240
    },
    {
      prop: 'name',
      label: '名称',
      type: 'text',
      disabled: true,
      isEdit: false,
      width: 160
    },
    {
      prop: 'address',
      label: '地址',
      type: 'text',
      disabled: false,
      isEdit: false
    },
    {
      prop: 'ad',
      label: '下拉窗',
      type: 'slect',
      isEdit: false,
      disabled: false
    }
  ],
  tableData: [],
  actionList: [
    {
      name: '新增',
      type: 'text',
      size: 'mini',
      click: 'add'
    },
    {
      name: '编辑',
      type: 'text',
      size: 'mini',
      click: 'edit'
    }
  ]
}

import tableList from './Table.vue'
import config from '../config'

子组件 Table.vue

<template>
  <div class="search-table">
    <el-table ref="multipleTable" highlight-current-row border height="400" tooltip-effect="dark" :data="tableData" style="width: 100%" :class="editOnoff ? 'tb-edit' : 'tb-edit2'" @selection-change="handleSelectionChange" @row-click="handleCurrentChange">
      <el-table-column v-if="isShowSelection" type="selection" width="40" />
      <el-table-column v-for="(item, index) in tableColumnList" :key="index" :show-overflow-tooltip="true" :prop="item.prop" :label="item.label" :width="item.width">
        <template v-if="item.isEdit" v-slot="scope">
          <span>{{ scope.row[item.prop] }}</span>
        </template>
        <template v-else-if="item.type === 'text'" v-slot="scope">
          <el-input v-model="scope.row[item.prop]" size="small" placeholder="" :disabled="item.disabled" />
          <span>{{ scope.row[item.prop] }}</span>
        </template>
        <template v-else-if="item.type === 'time'" v-slot="scope">
          <el-date-picker v-model="scope.row[item.prop]" value-format="yyyy-MM-dd HH:mm:ss" type="datetime" :disabled="item.disabled" placeholder="选择日期时间" />
          <span>{{ scope.row[item.prop] }}</span>
        </template>
      </el-table-column>
      <el-table-column :show-overflow-tooltip="true" fixed="right" label="操作" :width="actionWidth">
        <template v-slot="scope">
          <el-button v-if="scope.row.id === editObj.id && editOnoff" type="text" size="small">保存</el-button>
          <el-button v-if="scope.row.id === editObj.id && editOnoff" type="text" size="small" @click.stop="editOnoff = false">取消</el-button>
          <el-button v-for="(subItem, subIndex) in actionList" :key="subIndex" :type="subItem.type" :size="subItem.size" @click.native.stop="handleClick(subItem.click, scope.row)">{{ subItem.name }}</el-button>
        </template>
      </el-table-column>
    </el-table>

    <div class="search-foot">
      <div v-if="isShowSelection" class="foot-left">
        共选 {{ total }} 条
      </div>
      <div class="foot-right">
        <m-page />
      </div>
    </div>

  </div>
</template>

<script>
import mPage from './CurrenPage.vue'
export default {
  components: { mPage },
  props: {
    isShowSelection: {
      type: Boolean,
      default: false
    },
    disabled: {
      type: Boolean,
      default: false
    },
    isEdit: {
      type: Boolean,
      default: false
    },
    tableColumnList: {
      type: Array,
      default: () => {
        return []
      }
    },
    options: {
      type: Array,
      default: () => {
        return []
      }
    },
    tableData: {
      type: Array,
      default: () => {
        return []
      }
    },
    actionList: {
      type: Array,
      default: () => {
        return []
      }
    },
    actionWidth: {
      type: String,
      default: ''
    }
  },
  data() {
    return {
      total: 0,
      name: '',
      editObj: {},
      editOnoff: false,
      isShowSlect: false
    }
  },
  watch: {
    tableData(val) {
      this.doLayout()
    }
  },
  mounted() {},
  methods: {
    handleClick(val, row) {
      const onClick = val
      this.$emit(onClick, row)
    },
    handleSelectionChange(val) {
      this.total = val.length
      this.$emit('handleSelectionChange')
    },
    handleCurrentChange(row) {
      this.editObj = JSON.parse(JSON.stringify(row))
      this.editOnoff = row.id === this.editObj.id
      this.$emit('handleCurrentChange', row)
    },
    doLayout() {
      this.$nextTick(() => {
        this.$refs.multipleTable.doLayout()
      })
    }
  }
}
</script>

<style lang="scss" scoped>
.search-table {
    .search-foot {
        width: 100%;
        height: 32px;
        line-height: 32px;
        display: flex;
    }
    .footer-span{
        margin: 0 4px 0 6px !important;
        cursor: pointer;
    }
    .footer-span:hover {
        color: blue;
    }
    .foot-left {
        width: 100px;
    }
    .foot-right {
        flex: 1;
        text-align: right;
    }
}
//表格的可编辑
    .tb-edit .el-input {
        display: none;
    }

    .tb-edit .current-row .el-input {
        display: block;
    }

    .tb-edit .current-row .el-input + span {
        display: none;
    }

    //取消
    .tb-edit2 .current-row .el-input + span {
        display: block;
    }
    .tb-edit2 .el-input {
        display: none;
    }
</style>

分页功能以及查询功能暂时还没完善,请各位大佬多提提意见,谢谢