vue 表格单元格内修改 demo

直接上代码把。

<template>
  <el-table v-if="modifyInfo.enable" :data="localList" @row-dblclick="rowDblclick">
    <template v-for="(item,index) in columns">
      <el-table-column :label="item[label]" :prop="item[prop]" :key="index">
        <template slot-scope="{row,$index,column}">
          <template
              v-if="item[modify] && $index === modifyInfo.updateIndex && modifyInfo.modifyEnable[column.property]">
            <el-input v-model="modifyInfo.newRow[item[prop]]"/>
          </template>
          <template v-else-if="item[customer]===true">
            <slot :name="item[prop]" v-bind:row="row" v-bind:$index="$index" v-bind:column="column"></slot>
          </template>
          <template v-else>
            {{ row[item[prop]] }}
          </template>
        </template>
      </el-table-column>
    </template>
    <el-table-column label="操作">
      <template slot-scope="{row,$index,column}">
        <el-button v-if="modifyInfo.enable && modifyInfo.updateIndex===row.tableIndex"
                   @click="submitModify($index)" type="warning">修改
        </el-button>
        <slot name="operate" v-bind:row="row" v-bind:$index="$index" v-bind:column="column"></slot>
      </template>
    </el-table-column>
  </el-table>
</template>

<script>
export default {
  name: "jwModifyTable",
  props: {
    columns: {
      type: Array,
      required: true,
      default() {
        return [{label: '', prop: '', modify: false}]
      }
    },
    data: {
      type: Array,
      required: true
    },
    label: {
      type: String,
      require: false,
      default: 'label'
    },
    prop: {
      type: String,
      require: false,
      default: 'prop'
    },
    modify: {
      type: String,
      require: false,
      default: 'modify'
    },
    customer: {
      type: String,
      require: false,
      default: 'customer'
    },
  },
  watch: {
    columns: {
      handler(val, val2) {
        const obj = this.modifyInfo.modifyEnable = this.initEnable = {}
        const prop = this.prop
        val.forEach((item, index) => {
          if (item[this.modify]) {
            obj[item[prop]] = false
          }
        })
        this.initEnable = Object.assign({}, obj)
      },
      deep: true,
      immediate: true
    },
    data: {
      handler(val, val2) {
        this.resetModify()
        this.localList = val.map((item, index) => {
          return {...item, tableIndex: index}
        })
        this.modifyInfo.enable = true
      },
      deep: true
    },
  },
  data() {
    return {
      modifyInfo: {
        enable: false,
        updateIndex: -1,
        modifyEnable: {},
        oldRow: null,
        newRow: null,
      },
      initEnable: {},
      localList: []
    }
  },
  methods: {
    submitModify($index) {
      if ((!this.modifyInfo.enable) || $index !== this.modifyInfo.updateIndex) {
        return
      }
      const obj = {oldRow: this.modifyInfo.oldRow}
      const newModifyField = {}
      const oldRow = this.modifyInfo.oldRow
      const newRow = this.modifyInfo.newRow
      let key, value
      let arr = Object.keys(newRow )
      for (key of arr) {
        if ((value = newRow[key]) !== oldRow[key]) {
          newModifyField[key] = value
        }
      }
      obj['modifyField'] = newModifyField
      this.$emit("submitModify", obj)
    },
    resetModify(reset) {
      if (true === reset) {
        this.modifyInfo = this.$options.data().modifyInfo
      } else {
        this.modifyInfo = Object.assign({}, this.$options.data().modifyInfo, {
          enable: this.modifyInfo.enable,
          modifyEnable: {...this.initEnable},
        })
      }
    },
    rowDblclick(row, column, event) {
      if (!this.modifyInfo.enable) {
        return
      }
      if (!this.modifyInfo.modifyEnable.hasOwnProperty(column.property)) {
        return;
      }
      if ((!this.modifyInfo.newRow) || row.tableIndex !== this.modifyInfo.newRow.tableIndex) {
        //新行
        this.resetModify()
        this.modifyInfo.newRow = Object.assign({}, row)
        this.modifyInfo.oldRow = row
      }
      this.modifyInfo.updateIndex = row.tableIndex
      this.modifyInfo.modifyEnable[column.property] = true
    }
  }
}
</script>

<style scoped>

</style>

调用

 <jw-modify-table :data="[{name:'张三',gender:'人妖'}]"
                         :columns="[{label: '姓名', prop: 'name', modify: true, customer: true},
                         {label: '性别', prop: 'gender', modify: false, customer: false},]"
                         @submitModify="submitModify">
          <template v-slot:operate="{row,$index,column}">
            {{ 'customer' }}
          </template>
          <template v-slot:name="{row,$index,column}">
            {{ row.name + 'customer' }}
          </template>
</jw-modify-table>

效果

点击后效果

image

缺陷就是暂时无法动态使用slot自定义列数据

1 个赞

龙,发到【技术交流】模块去。

好了