用vue3和ant design实现:创建一个表格,并限制表格内容不能为空

一、表格内容不能为空的实现逻辑

function save(key: string) {
  // 先用 Object.keys(editableData[key]) 获取 editableData 中指定键对应的对象的所有属性键
  // 再用 some 方法来检查是否有属性的值为空
  if (Object.keys(editableData[key]).some(field => editableData[key][field] === '')) {
    alert('请输入');
  } else {
    Object.assign(dataSource.value.find(item => key === item.key), editableData[key]);
    delete editableData[key];
  }
}

1.Object.keys()

Object.keys() 返回一个数组,其元素是字符串,用于直接在对象上找到的可枚举的字符串键属性名。示例:

const arr = ["a", "b", "c"];
console.log(Object.keys(arr)); // ['0', '1', '2']

2.some() 

 用来检测数组中的元素是否满足指定条件.

(1)若有一个元素符合条件,则返回true,且后面的元素不会再检测。

(2)不会对空数组进行检测,不会改变原数组

filter()、some()、every()方法的区别 - 掘金 (juejin.cn)

3.Object.assign(target,...sources) 

将一个或者多个源对象中所有可枚举的复制到目标对象,并返回修改后的目标对象。 

target:需要应用源对象属性的目标对象,修改后将作为返回值。

sources:一个或多个包含要应用的属性的源对象。

const target = { a: 1, b: 2 };
const source = { b: 4, c: 5 };

const returnedTarget = Object.assign(target, source);

console.log(target);
// Expected output: Object { a: 1, b: 4, c: 5 }

console.log(returnedTarget === target);
// Expected output: true

4.find()

返回通过测试的数组的第一个元素的值。为数组中的每个元素都调用一次函数执行,当数组中的元素在测试条件时返回true,find()返回符合条件的元素,之后的值不会再执行函数。如果没有符合条件的元素则返回undefined。

 var arr = [1,2,3,4,5,6,7];
 var ar = arr.find(function(elem){
     return elem>5;
 });
 console.log(ar);//6
console.log(arr);//[1,2,3,4,5,6,7]

js数组中的find、filter、forEach、map四个方法的详解和应用实例_js find-CSDN博客

二、创建表格 

Table - Ant Design Vue (antdv.com)

使用Ant design组件库a-table

三、完整代码

1.template

<template>
  <a-table :columns="columns" :data-source="dataSource" bordered>
    <template #bodyCell="{ column, text, record }">
      <template v-if="column.dataIndex === 'name'">
        <div>
          <!-- record 是一个对象,代表表格中的一行数据。它包含了该行数据的各个字段的值。
            key 是 record 对象中的一个属性,用于唯一标识该行数据。在这段代码中,key 用于获取和设置 editableData 对象中对应行数据的可编辑状态。
            当 v-if="editableData[record.key]" 为真时,表示该行数据处于可编辑状态,此时会显示一个输入框(a-input)来编辑该行数据的 name 字段的值。而当 v-else 为真时,表示该行数据不可编辑,此时会直接显示该行数据的 name 字段的值。 -->
          <template v-if="editableData[record.key]">
            <a-input
              v-model:value="editableData[record.key][column.dataIndex]"
              style="margin: -5px 0"
            />
          </template>
          <template v-else>
            {{ text }}
          </template>
        </div>
      </template>
      <template v-if="column.dataIndex === 'age'">
        <div>
          <a-input
            v-if="editableData[record.key]"
            v-model:value="editableData[record.key][column.dataIndex]"
            style="margin: -5px 0"
          />
          <template v-else>
            {{ text }}
          </template>
        </div>
      </template>
      <template v-if="column.dataIndex === 'address'">
        <div>
          <a-input
            v-if="editableData[record.key]"
            v-model:value="editableData[record.key][column.dataIndex]"
            style="margin: -5px 0"
          />
          <template v-else>
            {{ text }}
          </template>
        </div>
      </template>
      <template v-else-if="column.dataIndex === 'operation'">
        <div class="editable-row-operations">
          <span v-if="editableData[record.key]">
            <a-typography-link @click="save(record.key)">
              Save
            </a-typography-link>
            <a-popconfirm title="Sure to cancel?" @confirm="cancel(record.key)">
              <a>Cancel</a>
            </a-popconfirm>
          </span>
          <span v-else>
            <a @click="edit(record.key)">Edit</a>
          </span>
        </div>
      </template>
    </template>
  </a-table>
</template>

2.script

<script lang="ts" setup>
import { cloneDeep } from 'lodash-es'
import { reactive, ref } from 'vue'
import type { UnwrapRef } from 'vue'

const columns = [
  {
    title: 'name',
    dataIndex: 'name',
    width: '25%',
  },
  {
    title: 'age',
    dataIndex: 'age',
    width: '15%',
  },
  {
    title: 'address',
    dataIndex: 'address',
    width: '40%',
  },
  {
    title: 'operation',
    dataIndex: 'operation',
  },
]

interface DataItem {
  key: string
  name: string
  age: number
  address: string
}

const data: DataItem[] = []
// 表格数据在这里显示
for (let i = 0; i < 100; i++) {
  data.push({
    key: i.toString(),
    name: `Edrward ${i}`,
    age: i,
    address: `London Park no. ${i}`,
  })
}

// 点了编辑前的数据
const dataSource = ref(data)
// 点了编辑后的数据
const editableData: UnwrapRef<Record<string, DataItem>> = reactive({})
// const tableFormRef = ref()

const edit = (key: string) => {
  editableData[key] = cloneDeep(
    dataSource.value.filter((item) => key === item.key)[0],
  )
}

// save(record.key, column.dataIndex)
function save(key: string) {
  if (Object.keys(editableData[key]).some(field => editableData[key][field] === '')) {
    alert('请输入');
  } else {
    Object.assign(dataSource.value.find(item => key === item.key), editableData[key]);
    delete editableData[key];
  }
}

const cancel = (key: string) => {
  delete editableData[key]
}
</script>

3.style

<style scoped>
.editable-row-operations a {
  margin-right: 8px;
}
</style>

四、效果

使用ant design vue

Ant design + Vue_vue antdv4, 按需引入-CSDN博客

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值