第十七课时: 可编辑表格的实现

1、JSX进阶

item.render = (h, { row, index, column }) => {
            // keyArr等于this.insideData[index].edittingKeyArr,如果this.insideData[index].edittingKeyArr没有值就为undefined
            const keyArr = this.insideData[index] ? this.insideData[index].edittingKeyArr : []
            return (
              <div>
                { keyArr && keyArr.indexOf(column.key) > -1
                  ? <i-input value={row[column.key]} on-input=z{this.handleInput.bind(this, row, index, column)}></i-input> : row[column.key] }
                <i-button on-click={() => { this.handleClick({ row, index, column }) }}>{ keyArr && keyArr.indexOf(column.key) > -1 ? '保存' : '编辑' }</i-button>
              </div>
            )
          }
          return item

2、单个单元格编辑表格

table.vue 表格父组件

<template>
  <div>
    <!-- 单个单元格编辑表格 -->
    <edit-table :columns="columns" v-model="tableData" @on-edit="handleEdit"></edit-table>
    <!-- <edit-table-mul :columns="columns" v-model="tableData"></edit-table-mul> -->
    <!-- 多个单元格编辑表格 -->
    <edit-table-mul-wang v-if="tableShow" :columns="columns" v-model="tableData"></edit-table-mul-wang>

  </div>
</template>

<script>
import { getTableData } from '@/api/data'
import EditTable from '_c/edit-table'
import EditTableMul from '_c/edit-table-mul'
import EditTableMulWang from '_c/edit-table-mul-wang'

export default {
  components: {
    EditTable,
    EditTableMul,
    EditTableMulWang
  },
  data () {
    return {
      tableData: [],
      tableShow: false,
      columns: [
        { key: 'name', title: '姓名' },
        { key: 'age', title: '年龄', editable: true },
        { key: 'email', title: '邮箱', editable: true }
      ]
    }
  },
  methods: {
    handleEdit ({ row, index, column, newValue }) {
      console.log(row, index, column, newValue)
    }
  },
  mounted () {
    getTableData().then(res => {
      this.tableData = res
      this.tableShow = true
    })
  }
}
</script>

edit-table.vue 子组件

<template>
  <Table :columns="insideColumns" :data="value"></Table>
</template>

<script>
import clonedeep from 'clonedeep'
export default {
  name: 'EditTable',
  data () {
    return {
      insideColumns: [],
      edittingId: '',
      edittingContent: ''
    }
  },
  props: {
    columns: {
      type: Array,
      default: () => []
    },
    value: {
      type: Array,
      default: () => []
    }
  },
  watch: {
    columns () {
      this.handleColumns()
    }
  },
  methods: {
    handleClick ({ row, index, column }) {
      // 如果点击保存按钮
      if (this.edittingId === `${column.key}_${index}`) {
        // 深复制传入的value值
        let tableData = clonedeep(this.value)
        // 赋值
        tableData[index][column.key] = this.edittingContent
        this.$emit('input', tableData)
        this.$emit('on-edit', { row, index, column, newValue: this.edittingContent })
        this.edittingId = ''
        this.edittingContent = ''
      } else {
        this.edittingId = `${column.key}_${index}`
      }
    },
    handleInput (newValue) {
      this.edittingContent = newValue
    },
    handleColumns () {
      const insideColumns = this.columns.map(item => {
        // 判断table列有没有传入的render函数或者editable属性
        if (!item.render && item.editable) {
          item.render = (h, { row, index, column }) => {
            // 刚开始this.edittingId != `${column.key}_${index}`所以isEditting等于false
            const isEditting = this.edittingId === `${column.key}_${index}`
            return (
              <div>
                {isEditting ? <i-input value={row[column.key]} style="width: 50px;" on-input={this.handleInput}></i-input> : <span>{row[column.key]}</span>}
                <i-button on-click={this.handleClick.bind(this, { row, index, column })}>{ isEditting ? '保存' : '编辑' }</i-button>
              </div>
            )
          }
          return item
        } else return item
      })
      this.insideColumns = insideColumns
    }
  },
  mounted () {
    this.handleColumns()
  }
}
</script>

3、多单元格编辑表格

edit-table-mul.vue

<template>
  <Table :columns="insideColumns" :data="value"></Table>
</template>

<script>
import clonedeep from 'clonedeep'
export default {
  name: 'EditTable',
  data () {
    return {
      insideData: [],
      insideColumns: []
    }
  },
  props: {
    columns: {
      type: Array,
      default: () => []
    },
    value: {
      type: Array,
      default: () => []
    }
  },
  watch: {
    value () {
      this.handleColumns()
    }
  },
  methods: {
    handleClick ({ row, index, column }) {
      // keyIndex为选中column.key在this.insideData[index].edittingKeyArr中的值
      let keyIndex = this.insideData[index].edittingKeyArr ? this.insideData[index].edittingKeyArr.indexOf(column.key) : -1
      let rowObj = this.insideData[index]
      // 如果已经点击了
      if (keyIndex > -1) {
        // 删除rowObj.edittingKeyArr数组中的column.key
        rowObj.edittingKeyArr.splice(keyIndex, 1)
        // 把rowObj替换到insideData数组中
        this.insideData.splice(index, 1, rowObj)
        this.$emit('input', this.insideData)
        this.$emit('on-edit', { row, index, column, newValue: this.insideData[index][column.key] })
      } else {
        // 还没有点击
        // 把column.key放入rowObj.edittingKeyArr中
        rowObj.edittingKeyArr = (rowObj.edittingKeyArr) ? [...rowObj.edittingKeyArr, column.key] : [column.key]
        // 把rowObj替换到insideData数组中
        this.insideData.splice(index, 1, rowObj)
      }
    },
    handleInput (row, index, column, newValue) {
      this.insideData[index][column.key] = newValue
    },
    handleColumns () {
      this.insideData = clonedeep(this.value)
      const insideColumns = this.columns.map(item => {
        if (!item.render && item.editable) {
          item.render = (h, { row, index, column }) => {
            // keyArr等于this.insideData[index].edittingKeyArr,如果this.insideData[index].edittingKeyArr没有值就为undefined
            const keyArr = this.insideData[index] ? this.insideData[index].edittingKeyArr : []
            return (
              <div>
                { keyArr && keyArr.indexOf(column.key) > -1
                  ? <i-input value={row[column.key]} on-input={this.handleInput.bind(this, row, index, column)}></i-input> : row[column.key] }
                <i-button on-click={() => { this.handleClick({ row, index, column }) }}>{ keyArr && keyArr.indexOf(column.key) > -1 ? '保存' : '编辑' }</i-button>
              </div>
            )
          }
          return item
        } else return item
      })
      this.insideColumns = insideColumns
    }
  },
  mounted () {
    this.handleColumns()
  }
}
</script>
    原文作者:岳_轻风
    原文地址: https://segmentfault.com/a/1190000018425153
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞