使用Vue 3 + ts 实现可动态添加行的表格表单

使用Vue 3 + TypeScript 实现可动态添加行的表格表单

<template>
  <el-form :model="formData" ref="formRef" label-width="100px">
    <el-table :data="formData.rows" border>
      <el-table-column label="序号" width="70">
        <template #default="{ $index }">
          {{ $index + 1 }}
        </template>
      </el-table-column>
      <el-table-column label="名称" prop="name">
        <template #default="{ row }">
          <el-input v-model="row.name"></el-input>
        </template>
      </el-table-column>
      <el-table-column label="图片" prop="image">
        <template #default="{ row }">
          <el-upload
            action="#"
            list-type="picture-card"
            :auto-upload="false"
            :on-change="(file) => handleImageChange(file, row)"
          >
            <i class="el-icon-plus"></i>
          </el-upload>
        </template>
      </el-table-column>
      <el-table-column label="视频" prop="video">
        <template #default="{ row }">
          <el-upload
            action="#"
            :auto-upload="false"
            :on-change="(file) => handleVideoChange(file, row)"
          >
            <el-button size="small" type="primary">上传视频</el-button>
          </el-upload>
        </template>
      </el-table-column>
      <el-table-column label="备注" prop="remark">
        <template #default="{ row }">
          <el-input v-model="row.remark" type="textarea"></el-input>
        </template>
      </el-table-column>
    </el-table>
    
    <el-button @click="addRow" :disabled="formData.rows.length >= 6" style="margin-top: 10px;">
      添加行
    </el-button>
    
    <el-button type="primary" @click="submitForm" style="margin-top: 20px;">
      提交
    </el-button>
  </el-form>
</template>

<script lang="ts" setup>
import { reactive, ref } from 'vue'
import { ElMessage } from 'element-plus'
import type { UploadFile } from 'element-plus'

interface RowData {
  name: string
  image: string
  video: string
  remark: string
}

const formRef = ref()
const formData = reactive({
  rows: [] as RowData[]
})

const addRow = () => {
  if (formData.rows.length < 6) {
    formData.rows.push({
      name: '',
      image: '',
      video: '',
      remark: ''
    })
  }
}

const handleImageChange = (file: UploadFile, row: RowData) => {
  row.image = URL.createObjectURL(file.raw!)
}

const handleVideoChange = (file: UploadFile, row: RowData) => {
  row.video = URL.createObjectURL(file.raw!)
}

const submitForm = async () => {
  try {
    await formRef.value.validate()
    // 调用后端API
    const response = await fetch('/api/addRows', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(formData.rows),
    })
    
    if (response.ok) {
      ElMessage.success('提交成功')
      // 重置表单
      formData.rows = []
    } else {
      ElMessage.error('提交失败')
    }
  } catch (error) {
    console.error('表单验证失败:', error)
    ElMessage.error('表单验证失败,请检查输入')
  }
}
</script>

这个示例实现了以下功能:

  1. 使用el-formel-table来创建一个可编辑的表格。
  2. 表格包含序号、名称、图片、视频和备注五列。
  3. 使用el-upload组件处理图片和视频的上传。
  4. 通过addRow函数实现动态添加行,最多可添加6行。
  5. 使用submitForm函数处理表单提交,包括表单验证和调用后端API。

注意事项:

  • 这个示例中,图片和视频上传使用了URL.createObjectURL来创建本地预览URL。在实际应用中,你可能需要将文件上传到服务器,并使用服务器返回的URL。
  • 后端API的URL(/api/addRows)需要根据实际后端接口来调整。
  • 处理大文件(如视频)时,可能需要考虑分片上传等优化措施。

关注微信公众号温暖前端,不定期分享前端知识点和前端资料↓↓↓

  • 6
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
首先,需要安装Vue3、TypeScript和Element Plus。 安装命令: ``` npm install vue@next vue-router@next typescript@latest --save-dev npm install element-plus --save ``` 接下来,创建一个Vue3 TypeScript项目,并在`main.ts`中引入Element Plus。 ```typescript import { createApp } from 'vue'; import App from './App.vue'; import router from './router'; import ElementPlus from 'element-plus'; import 'element-plus/lib/theme-chalk/index.css'; const app = createApp(App); app.use(router); app.use(ElementPlus); app.mount('#app'); ``` 在`App.vue`中,创建一个,包括车牌号码和设备号码两个输入框,并添加一个绑定按钮。 ```html <template> <div class="app"> <form class="form"> <el-form-item label="车牌号码"> <el-input v-model="carNumber"></el-input> </el-form-item> <el-form-item label="设备号码"> <el-input v-model="deviceNumber"></el-input> </el-form-item> <el-form-item> <el-button type="primary" @click="bindDevice">绑定</el-button> </el-form-item> </form> </div> </template> <script lang="ts"> import { defineComponent, ref } from 'vue'; export default defineComponent({ name: 'App', setup() { const carNumber = ref(''); const deviceNumber = ref(''); const bindDevice = () => { // TODO: 实现绑定设备的逻辑 }; return { carNumber, deviceNumber, bindDevice, }; }, }); </script> ``` 在`bindDevice`方法中,可以调用API将车辆和设备进绑定。这里使用mock数据模拟API请求。 ```typescript const bindDevice = () => { // TODO: 实现绑定设备的逻辑 console.log(`车牌号码:${carNumber.value},设备号码:${deviceNumber.value}`); // mock API请求 setTimeout(() => { console.log('绑定成功!'); carNumber.value = ''; deviceNumber.value = ''; }, 2000); }; ``` 最后,运项目即可看到界面和绑定设备的功能。 完整代码如下: ```html <template> <div class="app"> <form class="form"> <el-form-item label="车牌号码"> <el-input v-model="carNumber"></el-input> </el-form-item> <el-form-item label="设备号码"> <el-input v-model="deviceNumber"></el-input> </el-form-item> <el-form-item> <el-button type="primary" @click="bindDevice">绑定</el-button> </el-form-item> </form> </div> </template> <script lang="ts"> import { defineComponent, ref } from 'vue'; export default defineComponent({ name: 'App', setup() { const carNumber = ref(''); const deviceNumber = ref(''); const bindDevice = () => { console.log(`车牌号码:${carNumber.value},设备号码:${deviceNumber.value}`); // mock API请求 setTimeout(() => { console.log('绑定成功!'); carNumber.value = ''; deviceNumber.value = ''; }, 2000); }; return { carNumber, deviceNumber, bindDevice, }; }, }); </script> <style scoped> .app { display: flex; justify-content: center; align-items: center; height: 100vh; } .form { width: 400px; } </style> ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

温暖前端

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值