joken-前端工程师

  :: 首页 :: 博问 :: 闪存 :: 新随笔 :: :: :: 管理 ::

当然可以!下面是使用 TypeScript 语法的动态表单弹出组件示例。

1. 创建动态表单弹出组件(TypeScript)

<template>
  <el-dialog :visible.sync="visible" title="表单" @close="handleClose">
    <el-form :model="formData" :rules="rules" ref="formRef">
      <el-form-item
        v-for="(item, index) in formItems"
        :key="index"
        :label="item.label"
        :prop="item.prop"
      >
        <component :is="item.type" v-model="formData[item.prop]" v-bind="item.props" />
      </el-form-item>
    </el-form>
    <span slot="footer" class="dialog-footer">
      <el-button @click="handleClose">取消</el-button>
      <el-button type="primary" @click="handleSubmit">提交</el-button>
    </span>
  </el-dialog>
</template>

<script lang="ts">
import { ref, defineComponent } from 'vue';

interface FormItem {
  label: string;
  prop: string;
  type: string;
  props?: Record<string, any>;
}

export default defineComponent({
  props: {
    visible: {
      type: Boolean,
      required: true,
    },
    formItems: {
      type: Array as () => FormItem[],
      required: true,
    },
    rules: {
      type: Object,
      required: true,
    },
    initialData: {
      type: Object,
      default: () => ({}),
    },
  },
  setup(props, { emit }) {
    const formData = ref<{ [key: string]: any }>({ ...props.initialData });

    const handleClose = () => {
      emit('update:visible', false);
    };

    const handleSubmit = async () => {
      const formRef = refs.formRef;
      try {
        await formRef.validate();
        emit('submit', formData.value);
        handleClose();
      } catch (error) {
        console.error('表单验证失败', error);
      }
    };

    return {
      formData,
      handleClose,
      handleSubmit,
    };
  },
});
</script>

2. 在父组件中使用动态表单弹出组件(TypeScript)

<template>
  <div>
    <el-button type="primary" @click="showDialog">新增</el-button>
    <el-table :data="tableData" style="width: 100%">
      <el-table-column prop="name" label="姓名" />
      <el-table-column prop="age" label="年龄" />
      <el-table-column prop="gender" label="性别" />
      <el-table-column label="操作">
        <template #default="{ row }">
          <el-button @click="editRow(row)">编辑</el-button>
        </template>
      </el-table-column>
    </el-table>

    <form-dialog
      :visible="dialogVisible"
      :formItems="formItems"
      :rules="rules"
      :initialData="currentRow"
      @update:visible="dialogVisible = $event"
      @submit="handleFormSubmit"
    />
  </div>
</template>

<script lang="ts">
import { ref, defineComponent } from 'vue';
import FormDialog from './FormDialog.vue';

interface TableData {
  id: number;
  name: string;
  age: number;
  gender: string;
}

export default defineComponent({
  components: {
    FormDialog,
  },
  setup() {
    const dialogVisible = ref(false);
    const currentRow = ref<TableData | {}>({});
    const tableData = ref<TableData[]>([]);

    const formItems = [
      { label: '姓名', prop: 'name', type: 'el-input', placeholder: '请输入姓名' },
      { label: '年龄', prop: 'age', type: 'el-input', placeholder: '请输入年龄' },
      {
        label: '性别',
        prop: 'gender',
        type: 'el-select',
        props: {
          placeholder: '请选择性别',
          options: [
            { label: '男', value: 'male' },
            { label: '女', value: 'female' },
          ],
        },
      },
    ];

    const rules = {
      name: [{ required: true, message: '姓名是必填项', trigger: 'blur' }],
      age: [{ required: true, message: '年龄是必填项', trigger: 'blur' }],
      gender: [{ required: true, message: '性别是必填项', trigger: 'change' }],
    };

    const showDialog = () => {
      dialogVisible.value = true;
      currentRow.value = {}; // Reset for new entry
    };

    const editRow = (row: TableData) => {
      currentRow.value = { ...row }; // Copy row data for editing
      dialogVisible.value = true;
    };

    const handleFormSubmit = (formData: TableData) => {
      if ('id' in currentRow.value) {
        // Update existing row
        const index = tableData.value.findIndex(item => item.id === currentRow.value.id);
        if (index !== -1) {
          tableData.value[index] = { ...currentRow.value, ...formData };
        }
      } else {
        // Add new row
        tableData.value.push({ ...formData, id: Date.now() });
      }
      dialogVisible.value = false;
    };

    return {
      dialogVisible,
      currentRow,
      tableData,
      formItems,
      rules,
      showDialog,
      editRow,
      handleFormSubmit,
    };
  },
});
</script>

总结

这个示例展示了如何使用 TypeScript 语法创建动态表单弹出框,支持多种表单项类型,并处理新增和编辑功能。你可以根据需要扩展更多表单项和验证规则。

posted on 2024-07-13 15:46  joken1310  阅读(1)  评论(0编辑  收藏  举报