Ant Design Vue 之a-tab单元格编辑

前言

最近遇到一个需求,要求表格中某一属性是可以单独改变的。看了 Ant Design Vue 的官方组件,发现不太灵活,所以自己动手写了一下。

官方实现

先看一下官方demo演示效果

Snipaste_2021-04-27_14-51-41.png

发现只能整行编辑,不能单独针对某个属性进行单独编辑,例如只针对 name 或者 age 进行编辑。

手动调整

先看下效果

Snipaste_2021-04-27_15-04-32.png

在每列的后面增加了一个编辑icon ,点击后的效果如下

Snipaste_2021-04-27_15-06-31.png

整体效果如上图所示,此案例只展示了name

代码部分
<template>
  <a-table :columns='columns' :data-source='data' bordered>
    <template
      v-for="col in ['name']"
      :slot='col'
      slot-scope='text, record, index'
    >
      <div :key='col' style='float: left;margin-right: 0'>
        <a-input
          v-if='record.editable'
          style='margin: -5px 0'
          :value='text'
          @change='e => handleChange(e.target.value, record.key, col)'
        />
        <template v-else>
          {{ text }}
        </template>
      </div>
      <div style='float: right'>
           <span v-if='record.editable'>
             <a style='color: #2eabff;fontSize:15px;margin-left: 0;margin-right: 20px'  @click='() => save(record.key)' >确定</a>
          <a-popconfirm title='确认取消重命名?' @confirm='() => cancel(record.key)'>
            <a type='close' style='color: #2eabff;fontSize:15px' >取消</a>
          </a-popconfirm>
        </span>
        <span v-else>
          <a-icon style='color: #2eabff;fontSize:20px' type='edit'  :disabled="editingKey !== ''" @click='() => edit(record.key)' />
        </span>
      </div>
    </template>
  </a-table>
</template>
<script>
const columns = [
  {
    title: 'name',
    dataIndex: 'name',
    width: '25%',
    scopedSlots: { customRender: 'name' }
  },
  {
    title: 'age',
    dataIndex: 'age',
    width: '15%',
    scopedSlots: { customRender: 'age' }
  },
  {
    title: 'address',
    dataIndex: 'address',
    width: '40%',
    scopedSlots: { customRender: 'address' }
  },
  {
    title: 'operation',
    dataIndex: 'operation',
    scopedSlots: { customRender: 'operation' }
  }
]

const data = []
for (let i = 0; i < 100; i++) {
  data.push({
    key: i.toString(),
    name: `Edrward ${i}`,
    age: 32,
    address: `London Park no. ${i}`
  })
}
export default {
  data() {
    this.cacheData = data.map(item => ({ ...item }))
    return {
      data,
      columns,
      editingKey: ''
    }
  },
  methods: {
    handleChange(value, key, column) {
      const newData = [...this.data]
      const target = newData.filter(item => key === item.key)[0]
      if (target) {
        target[column] = value
        this.data = newData
      }
    },
    edit(key) {
      const newData = [...this.data]
      const target = newData.filter(item => key === item.key)[0]
      this.editingKey = key
      if (target) {
        target.editable = true
        this.data = newData
      }
    },
    save(key) {
      const newData = [...this.data]
      const newCacheData = [...this.cacheData]
      const target = newData.filter(item => key === item.key)[0]
      console.log("target:",JSON.stringify(target))
      const targetCache = newCacheData.filter(item => key === item.key)[0]
      if (target && targetCache) {
        delete target.editable
        this.data = newData
        Object.assign(targetCache, target)
        this.cacheData = newCacheData
      }
      this.editingKey = ''
    },
    cancel(key) {
      const newData = [...this.data]
      const target = newData.filter(item => key === item.key)[0]
      this.editingKey = ''
      if (target) {
        Object.assign(target, this.cacheData.filter(item => key === item.key)[0])
        delete target.editable
        this.data = newData
      }
    }
  }
}
</script>
<style scoped>

</style>

代码逻辑很简单,可以直接运行看下效果,如果想所有列都需编辑,扩充一下col ,定义一个变量,遍历需要编辑的列即可。例如

......伪代码.....
data() {
    return {
      editColumns:['name','age']//自行扩展即可
    }
  },

v-for="col in ['name'] 调整为 v-for="col in editColumns 即可。

总结

Ant Design Vue 本身组件还是十分强大的,但是不会总会和你的需求完美契合的,需要自己慢慢摸索,以上的效果可能不是很美观,本人后端程序员一枚,请勿见怪。

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Ant Design Vue的a-table组件默认不支持单元格合并,但是可以通过自定义渲染函数来实现单元格合并。以下是一个简单的示例代码: ```html <template> <a-table :columns="columns" :data-source="dataSource"></a-table> </template> <script> export default { data() { return { columns: [ { title: "姓名", dataIndex: "name", customRender: (text, row, index) => { const rowspan = row.age < 30 ? 2 : 1; // 根据条件设定行合并数 if (index % rowspan === 0) { return { children: text, attrs: { rowSpan: rowspan } }; } else { return { children: "", attrs: { rowSpan: 0 } }; } } }, { title: "年龄", dataIndex: "age" }, { title: "地址", dataIndex: "address" } ], dataSource: [ { name: "张三", age: 28, address: "北京市海淀区" }, { name: "李四", age: 32, address: "上海市浦东新区" }, { name: "王五", age: 25, address: "广州市天河区" }, { name: "赵六", age: 31, address: "深圳市福田区" } ] }; } }; </script> ``` 在上面的代码中,我们通过自定义渲染函数 `customRender` 来实现单元格的合并。在渲染姓名这一列时,根据条件设定行合并数,然后判断当前行是否是合并行的第一行,如果是就返回一个包含 `children` 和 `attrs` 属性的对象,其中 `children` 属性设置单元格显示的文本,`attrs` 属性设置单元格的 `rowspan` 属性。如果不是合并行的第一行,就返回一个空字符串和 `rowspan` 为 0 的 `attrs` 属性,表示该单元格不需要显示。 这样就能实现 Ant Design Vue 的 a-table 表格单元格合并了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值