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>
相关推荐
全宝7 分钟前
🌏【cesium系列】01.vue3+vite集成Cesium
前端·gis·cesium
拉不动的猪1 小时前
简单回顾下插槽透传
前端·javascript·面试
烛阴1 小时前
Fragment Shader--一行代码让屏幕瞬间变黄
前端·webgl
爱吃鱼的锅包肉1 小时前
Flutter路由模块化管理方案
前端·javascript·flutter
风清扬雨1 小时前
Vue3具名插槽用法全解——从零到一的详细指南
前端·javascript·vue.js
海盗强2 小时前
Vue 3 常见的通信方式
javascript·vue.js·ecmascript
大熊猫今天吃什么2 小时前
【一天一坑】空数组,使用 allMatch 默认返回true
前端·数据库
!win !2 小时前
Tailwind CSS一些你需要记住的原子类
前端·tailwindcss
前端极客探险家2 小时前
打造一个 AI 面试助手:输入岗位 + 技术栈 → 自动生成面试问题 + 标准答案 + 技术考点图谱
前端·人工智能·面试·职场和发展·vue
oscar9993 小时前
JavaScript与TypeScript
开发语言·javascript·typescript