vue3+element-plus表格自定义输入

      <el-table :data="tableData" style="width: 100%">
        <el-table-column
        v-for="(item, index) in tableHeader"
        :key="index"
      >
        <!-- 表头 -->
        <template #header>
          <span v-if="item">{{ item }}</span>
          <el-input @change="handleHeader" v-model="headerCont" v-else/>
        </template>
        <!-- 内容 -->
        <template #default="scope">
          <el-input v-model="scope.row[item]" @input="(val) => {handleAddRowData(val, item, scope.row)}"/>
        </template>
      </el-table-column>
      </el-table>
      <el-button @click="handleAddHeader">添加表头</el-button>
      <el-button @click="handleAddRow">添加行</el-button>

js

// 表头
const tableHeader = ref(['价格', '库存'])
// 表格数据
const tableData = ref([{
  '价格': '100',
  '库存': '100',
  idx: 1
},])
// 收集表头的数据
const headerCont = ref('')

// 添加表头
const handleAddHeader = () => {
  if(!tableHeader.value.every(item => !!item)) return ElMessage.error('请先填写表头内容')
  tableHeader.value.unshift('')
}
// 将表头更新 && 将表格数据更新
const handleHeader = (val) => {
  tableHeader.value.splice(0, 1, val)
  tableData.value = tableData.value.map(item => {
    return {...item, [val]: ''}
  })
  headerCont.value = ''
}

// 添加行
const handleAddRow = () => {
  const newTabelData = {}
  tableHeader.value.forEach(item => {
    newTabelData[item] = ''
  })
  newTabelData.idx = tableData.value.length+1
  tableData.value.push(newTabelData)
}

const handleAddRowData = (val, type, row) => {
  tableData.value = tableData.value.map(item => {
    if (item.idx === row.idx) {
      item[type] = val
    }
    return item
  })
}


// 获取表格数据
const handleClick = () => {
  const isOptions = ['库存', '价格']
  // 筛选的表格数据
  const subMitTable = tableHeader.value.map(item => {
    if (!isOptions.includes(item)) {
      const select = tableData.value.map(item1 => {
        return item1[item]
      })
      return {title: item, subTitle: select}
    }
  }).filter(item => !!item)
  console.log(subMitTable);
  console.log(tableData.value);
}

  • 11
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要写一个高级的通用的crud组件,可以遵循以下步骤: 1. 定义props - columns: 列定义,包括列名称、字段、是否可编辑等信息 - data: 数据源,需要是一个数组 - editable: 是否可编辑,控制表格是否可编辑 - rowKey: 行key,用于区分每一行数据的唯一标识 - showPagination: 是否显示分页器 - pageSizes: 分页器可选的每一页条数 - pageSize: 每一页的条数 - currentPage: 当前页码 2. 定义data - tableData: 表格数据源,需要在mounted中初始化,可以使用props中的data - currentPage: 当前页码,需要在mounted中初始化,可以使用props中的currentPage - total: 数据总数,需要在mounted中初始化,可以使用props中的data的长度 - pageSize: 每一页的条数,需要在mounted中初始化,可以使用props中的pageSize 3. 定义computed - displayedData: 显示的数据,根据当前页码和每一页的条数计算得出 - displayedColumns: 显示的列,根据传入的columns和editable计算得出 4. 定义methods - handleSizeChange: 分页器每一页条数改变时的回调函数,需要更新pageSize和total - handleCurrentChange: 分页器当前页码改变时的回调函数,需要更新currentPage - handleEdit: 表格中的编辑操作的回调函数,需要更新tableData中的对应数据 - handleDelete: 表格中的删除操作的回调函数,需要从tableData中删除对应数据 5. 定义template - 使用el-table组件展示数据源 - 使用v-if控制是否显示分页器 - 使用v-for循环展示列定义中的列 - 使用v-if控制列是否可编辑 - 使用slot插槽自定义每一行的操作列 完整的代码如下: ```vue <template> <div> <el-table :data="displayedData" :columns="displayedColumns"> <template #default="{row}"> <td> <slot name="operation" :row="row"></slot> </td> </template> </el-table> <el-pagination v-if="showPagination" :page-sizes="pageSizes" :page-size="pageSize" :current-page.sync="currentPage" :total="total" @size-change="handleSizeChange" @current-change="handleCurrentChange" /> </div> </template> <script> export default { name: 'CrudTable', props: { columns: { type: Array, default: () => [] }, data: { type: Array, default: () => [] }, editable: { type: Boolean, default: false }, rowKey: { type: String, default: 'id' }, showPagination: { type: Boolean, default: true }, pageSizes: { type: Array, default: () => [10, 20, 30, 40, 50] }, pageSize: { type: Number, default: 10 }, currentPage: { type: Number, default: 1 } }, data() { return { tableData: [], currentPage: 1, total: 0, pageSize: 10 } }, computed: { displayedData() { const start = (this.currentPage - 1) * this.pageSize const end = start + this.pageSize return this.tableData.slice(start, end) }, displayedColumns() { return this.columns.map(column => { const newColumn = { ...column } if (this.editable && column.editable) { newColumn.editable = true newColumn.scopedSlots = { default: scope => { return ( <el-input v-model={scope.row[column.prop]} size="mini" clearable /> ) } } } return newColumn }) } }, methods: { handleSizeChange(pageSize) { this.pageSize = pageSize this.total = this.tableData.length }, handleCurrentChange(currentPage) { this.currentPage = currentPage }, handleEdit(row) { const index = this.tableData.findIndex(item => item[this.rowKey] === row[this.rowKey]) if (index > -1) { this.tableData.splice(index, 1, row) } }, handleDelete(row) { const index = this.tableData.findIndex(item => item[this.rowKey] === row[this.rowKey]) if (index > -1) { this.tableData.splice(index, 1) } } }, mounted() { this.tableData = this.data this.currentPage = this.currentPage this.total = this.tableData.length this.pageSize = this.pageSize } } </script> ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值