vue3 ts 简单动态表单 和表格

ts 复制代码
<template>
  <div style="padding: 15px">
    <el-card>
      <el-form :inline="true" ref="formRef" :model="dynamicForm">
        <el-form-item
          v-for="(column, index) in dynamicForm.columns"
          :key="column.field + '.' + index"
          :label="column.label"
          :prop="column.prop"
        >
          <el-input v-model="column.value" />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="submitForm(formRef)"> 查询 </el-button>
          <el-button @click="resetForm(formRef)">重置</el-button>
        </el-form-item>
      </el-form>
      <div class="table">
        <el-button type="primary" size="small" @click="handleRefresh">刷新</el-button>
        <el-button type="success" size="small" @click="handleSave">添加</el-button>
        <el-button type="warning" size="small" @click="handleUpdate">编辑</el-button>
        <el-button type="danger" size="small" @click="handleRemove">删除</el-button>
        <el-button type="info" size="small" @click="handleExport">导出</el-button>
        <el-table
          ref="tableRef"
          :data="tableData"
          stripe
          style="width: 100%"
          @selection-change="handleSelectionChange"
        >
          <el-table-column type="selection" :selectable="selectable" width="55" />

          <el-table-column
            v-for="column in tableColumn"
            :key="column.field"
            :prop="column.prop"
            :label="column.label"
            :width="column.width"
          />

          <el-table-column fixed="right" label="操作" min-width="120">
            <template #default="scope">
              <el-button type="primary" size="small" @click="handleDetail(scope.$index, scope.row)"
                >查看</el-button
              >
              <el-button size="small" @click="handleEdit(scope.$index, scope.row)">
                编辑
              </el-button>
              <el-button type="danger" size="small" @click="handleDelete(scope.$index, scope.row)">
                删除
              </el-button>
            </template>
          </el-table-column>
        </el-table>
      </div>
      <div class="page">
        <el-pagination
          v-model:current-page="currentPage"
          v-model:page-size="pageSize"
          :page-sizes="pageSizes"
          layout="total, sizes, prev, pager, next, jumper"
          :total="total"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        />
      </div>
    </el-card>
  </div>
</template>
<style lang="css">
.page {
  padding: 15px;
}
</style>
<script setup lang="ts">
import { reactive, ref } from 'vue'
import type { FormInstance, TableInstance } from 'element-plus'

interface FormColumn {
  field: string
  label: string
  prop: string
  width: string
  value: string
}

interface TableColumn {
  field: string
  label: string
  prop: string
  width: string
}

const formRef = ref<FormInstance>()
const dynamicForm = reactive<{
  columns: FormColumn[]
}>({
  columns: [
    {
      prop: 'date',
      label: 'date',
      field: 'date',
      width: 'auto',
      value: '',
    },
    {
      prop: 'name',
      label: 'name',
      field: 'name',
      width: 'auto',
      value: '',
    },
    {
      prop: 'address',
      label: 'address',
      field: 'address',
      width: 'auto',
      value: '',
    },
  ],
})

const submitForm = async (formEl: FormInstance | undefined) => {
  if (!formEl) return
  await formEl.validate((valid, fields) => {
    if (valid) {
      console.log('submit!')
      console.log(dynamicForm)
    } else {
      console.log('error submit!', fields)
    }
  })
}

const resetForm = (formEl: FormInstance | undefined) => {
  if (!formEl) return
  dynamicForm.columns?.forEach((column) => {
    column.value = ''
  })
  formEl.resetFields()
}

const tableRef = ref<TableInstance>()

const selection = ref<object[]>([])

// eslint-disable-next-line @typescript-eslint/no-unused-vars
const selectable = (row: object) => []

const handleSelectionChange = (val: object[]) => {
  selection.value = val
}

const tableColumn: TableColumn[] = [
  {
    prop: 'date',
    label: 'date',
    field: 'date',
    width: 'auto',
  },
  {
    prop: 'name',
    label: 'name',
    field: 'name',
    width: 'auto',
  },
  {
    prop: 'address',
    label: 'address',
    field: 'address',
    width: 'auto',
  },
]
const tableData = [
  {
    date: '2016-05-03',
    name: 'Tom',
    address: 'No. 189, Grove St, Los Angeles',
  },
  {
    date: '2016-05-02',
    name: 'Tom',
    address: 'No. 189, Grove St, Los Angeles',
  },
  {
    date: '2016-05-04',
    name: 'Tom',
    address: 'No. 189, Grove St, Los Angeles',
  },
  {
    date: '2016-05-01',
    name: 'Tom',
    address: 'No. 189, Grove St, Los Angeles',
  },
]

const handleRefresh = () => {}

const handleSave = () => {}

const handleUpdate = () => {
  if (selection.value.length !== 1) {
    console.log(selection.value)
  }
}

const handleRemove = () => {
  if (selection.value.length === 0) {
    console.log(selection.value)
  }
}

const handleExport = () => {
  if (selection.value.length === 0) {
    console.log(selection.value)
  }
}

const handleDetail = (index: number, row: object) => {
  console.log(index, row)
}
const handleEdit = (index: number, row: object) => {
  console.log(index, row)
}
const handleDelete = (index: number, row: object) => {
  console.log(index, row)
}

const currentPage = ref(1)
const pageSize = ref(10)
const pageSizes = ref([10, 50, 100])
const total = ref(1000)

const handleSizeChange = (val: number) => {
  console.log(`${val} items per page`)
}
const handleCurrentChange = (val: number) => {
  console.log(`current page: ${val}`)
}
</script>
相关推荐
熊猫钓鱼>_>14 分钟前
动态网站发布部署核心问题详解
前端·nginx·容器化·网页开发·云服务器·静态部署
方也_arkling15 分钟前
elementPlus按需导入配置
前端·javascript·vue.js
爱吃大芒果26 分钟前
Flutter for OpenHarmony 实战: mango_shop 资源文件管理与鸿蒙适配
javascript·flutter·harmonyos
我的xiaodoujiao29 分钟前
使用 Python 语言 从 0 到 1 搭建完整 Web UI自动化测试学习系列 44--将自动化测试结果自动推送至钉钉工作群聊
前端·python·测试工具·ui·pytest
沛沛老爹31 分钟前
Web开发者转型AI:多模态Agent视频分析技能开发实战
前端·人工智能·音视频
David凉宸36 分钟前
vue2与vue3的差异在哪里?
前端·javascript·vue.js
Irene199136 分钟前
JavaScript字符串转数字方法总结
javascript·隐式转换
笔画人生41 分钟前
Cursor + 蓝耘API:用自然语言完成全栈项目开发
前端·后端
AC赳赳老秦1 小时前
外文文献精读:DeepSeek翻译并解析顶会论文核心技术要点
前端·flutter·zookeeper·自动化·rabbitmq·prometheus·deepseek
小宇的天下1 小时前
Calibre 3Dstack --每日一个命令day18【floating_trace】(3-18)
服务器·前端·数据库