vue3 ts 动态表单原理

ts 复制代码
<template>
  <div class="form">
    <el-form
      :inline="dynamicForm.inline"
      :label-width="dynamicForm.labelWidth"
      ref="formRef"
      :model="dynamicForm"
    >
      <el-form-item
        v-for="(column, index) in dynamicForm.columns"
        :key="column.columnName + '.' + index"
        :label="column.columnLabel"
        :prop="column.columnProp"
      >
        <el-input v-model="column.columnValue" />
      </el-form-item>

      <el-form-item v-if="dynamicForm.buttonEnabled">
        <el-button type="primary" @click="submitForm(formRef)"> 查询 </el-button>
        <el-button @click="resetForm(formRef)">重置</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>
<style lang="css"></style>
<script setup lang="ts">
import { ref } from 'vue'
import type { FormInstance } from 'element-plus'
interface FormColumn {
  columnName: string
  columnLabel: string
  columnType: string
  columnProp: string
  columnWidth: string
  columnValue?: object
  formElement?: string
  optionValue?: string
}
const formRef = ref<FormInstance>()
const formData = ref({})

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

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

const props = defineProps<{
  dynamicForm: {
    inline: boolean
    labelWidth: string
    columns: FormColumn[]
    buttonEnabled?: boolean
  }
}>()

const emit = defineEmits<{
  (e: 'submitForm', formData: object | undefined): void
  (e: 'resetForm'): void
}>()
console.log(props.dynamicForm.columns)
</script>

使用,数组转对象 对象转数组

ts 复制代码
const saveFormCallbak = () => {
  //console.log(saveForm)
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  const arr: any[][] = []
  saveForm.columns.forEach((colunm: FormColumn) => {
    arr.push([colunm.columnName, colunm.columnValue])
  })
  const obj = Object.fromEntries(arr)
  // console.log(obj)
  save(obj)
    .then(() => {
      loadDataPage()
    })
    .finally(() => {
      saveFormVisible.value = false
    })
}
const updateFormCallbak = () => {
  //console.log(updateForm)
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  const arr: any[][] = []
  updateForm.columns.forEach((colunm: FormColumn) => {
    arr.push([colunm.columnName, colunm.columnValue])
  })
  const obj = Object.fromEntries(arr)
  //console.log(obj)
  update(obj.id, obj)
    .then(() => {
      loadDataPage()
    })
    .finally(() => {
      updateFormVisible.value = false
    })
}

参考element-plus动态添加表单项

ts 复制代码
    <!-- <el-form-item
      v-for="(domain, index) in dynamicValidateForm.domains"
      :key="domain.columnName"
      :label="domain.columnLabel"
      :prop="'domains.' + index + '.value'"
      :rules="{
        required: true,
        message: 'domain can not be null',
        trigger: 'blur',
      }"
    >
      <el-input v-model="domain.value" />
      <el-button class="mt-2" @click.prevent="removeDomain(domain)"> Delete </el-button>
    </el-form-item> -->
相关推荐
Csvn16 小时前
Pinia 状态管理
前端
不减20斤不改头像16 小时前
手机一句话开发贪吃蛇!TRAE SOLO 移动端 AI 编程实测
前端·后端
xuankuxiaoyao16 小时前
Vue.js实践-组件基础下
前端·javascript·vue.js
小白学大数据16 小时前
JS 混淆加密下的 Python 爬虫解决方案
javascript·爬虫·python
一棵白菜16 小时前
Claude Code + Amazon Bedrock 使用指南
前端
大家的林语冰17 小时前
前端周刊:axios 疑遭朝鲜黑客“钓鱼“;CSS 新函数上线;npm 上线深色主题;Oxlint 兼容表;ESLint 支持 Temporal......
前端·javascript·css
哀木18 小时前
一个简单的套壳方案,就能让你的 Agent 少做重复初始化
前端
问心无愧051318 小时前
ctf show web入门27
前端
小村儿19 小时前
给 AI Agent 装上"长期记忆":Karpathy 的 LLM Wiki 思想,我做成了工具
前端·后端·ai编程
竹林81819 小时前
用ethers.js连接MetaMask实现Web3钱包登录:从踩坑到稳定运行的完整记录
前端·javascript