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
table.vue 表格父组件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 子组件api
<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>
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>