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>