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>
相关推荐
_r0bin_2 小时前
前端面试准备-7
开发语言·前端·javascript·fetch·跨域·class
IT瘾君2 小时前
JavaWeb:前端工程化-Vue
前端·javascript·vue.js
zhang98800002 小时前
JavaScript 核心原理深度解析-不停留于表面的VUE等的使用!
开发语言·javascript·vue.js
potender2 小时前
前端框架Vue
前端·vue.js·前端框架
站在风口的猪11082 小时前
《前端面试题:CSS预处理器(Sass、Less等)》
前端·css·html·less·css3·sass·html5
程序员的世界你不懂3 小时前
(9)-Fiddler抓包-Fiddler如何设置捕获Https会话
前端·https·fiddler
MoFe13 小时前
【.net core】天地图坐标转换为高德地图坐标(WGS84 坐标转 GCJ02 坐标)
java·前端·.netcore
去旅行、在路上3 小时前
chrome使用手机调试触屏web
前端·chrome
Aphasia3114 小时前
模式验证库——zod
前端·react.js
lexiangqicheng4 小时前
es6+和css3新增的特性有哪些
前端·es6·css3