src/views/example/DynamicTableExample.vue
@@ -1,101 +1,91 @@
<template>
  <div class="app-container">
    <div class="search-form">
      <el-form :inline="true" :model="searchForm">
      <el-form :inline="true"
               :model="searchForm">
        <el-form-item label="部门">
          <el-input
            v-model="searchForm.department"
            placeholder="请输入部门名称"
            clearable
            style="width: 200px"
          />
          <el-input v-model="searchForm.department"
                    placeholder="请输入部门名称"
                    clearable
                    style="width: 200px" />
        </el-form-item>
        <el-form-item label="姓名">
          <el-input
            v-model="searchForm.name"
            placeholder="请输入姓名"
            clearable
            style="width: 200px"
          />
          <el-input v-model="searchForm.name"
                    placeholder="请输入姓名"
                    clearable
                    style="width: 200px" />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="handleSearch">搜索</el-button>
          <el-button type="primary"
                     @click="handleSearch">搜索</el-button>
          <el-button @click="handleReset">重置</el-button>
          <el-button type="success" @click="handleAdd">新增</el-button>
          <el-button type="success"
                     @click="handleAdd">新增</el-button>
        </el-form-item>
      </el-form>
    </div>
    <div class="table-container">
      <DynamicTable
        ref="dynamicTableRef"
        :data="tableData"
        :dict-types="dictTypes"
        :loading="loading"
        :show-selection="true"
        :show-actions="true"
        :show-pagination="true"
        :pagination="pagination"
        height="calc(100vh - 280px)"
        @selection-change="handleSelectionChange"
        @edit="handleEdit"
        @delete="handleDelete"
        @select-change="handleSelectChange"
        @input-change="handleInputChange"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
      <DynamicTable ref="dynamicTableRef"
                    :data="tableData"
                    :dict-types="dictTypes"
                    :loading="loading"
                    :show-selection="true"
                    :show-actions="true"
                    :show-pagination="true"
                    :pagination="pagination"
                    height="calc(100vh - 280px)"
                    @selection-change="handleSelectionChange"
                    @edit="handleEdit"
                    @delete="handleDelete"
                    @select-change="handleSelectChange"
                    @input-change="handleInputChange"
                    @size-change="handleSizeChange"
                    @current-change="handleCurrentChange" />
    </div>
    <!-- 新增/编辑对话框 -->
    <el-dialog
      v-model="dialogVisible"
      :title="dialogTitle"
      width="600px"
      append-to-body
    >
      <el-form
        ref="formRef"
        :model="form"
        :rules="rules"
        label-width="100px"
      >
        <el-form-item label="部门" prop="department">
          <el-input v-model="form.department" placeholder="请输入部门" />
    <el-dialog v-model="dialogVisible"
               :title="dialogTitle"
               width="600px"
               append-to-body>
      <el-form ref="formRef"
               :model="form"
               :rules="rules"
               label-width="100px">
        <el-form-item label="部门"
                      prop="department">
          <el-input v-model="form.department"
                    placeholder="请输入部门" />
        </el-form-item>
        <el-form-item label="姓名" prop="name">
          <el-input v-model="form.name" placeholder="请输入姓名" />
        <el-form-item label="姓名"
                      prop="name">
          <el-input v-model="form.name"
                    placeholder="请输入姓名" />
        </el-form-item>
        <el-form-item label="工号" prop="employeeId">
          <el-input v-model="form.employeeId" placeholder="请输入工号" />
        <el-form-item label="工号"
                      prop="employeeId">
          <el-input v-model="form.employeeId"
                    placeholder="请输入工号" />
        </el-form-item>
        <!-- 动态表单项:根据字典生成 -->
        <el-form-item
          v-for="dictItem in dynamicFormItems"
          :key="dictItem.value"
          :label="dictItem.label"
          :prop="dictItem.value"
        >
          <el-select
            v-model="form[dictItem.value]"
            placeholder="请选择"
            style="width: 100%"
          >
            <el-option
              v-for="option in dictItem.options"
              :key="option.value"
              :label="option.label"
              :value="option.value"
            />
        <el-form-item v-for="dictItem in dynamicFormItems"
                      :key="dictItem.value"
                      :label="dictItem.label"
                      :prop="dictItem.value">
          <el-select v-model="form[dictItem.value]"
                     placeholder="请选择"
                     style="width: 100%">
            <el-option v-for="option in dictItem.options"
                       :key="option.value"
                       :label="option.label"
                       :value="option.value" />
          </el-select>
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary"
                     @click="handleSubmit">确定</el-button>
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button type="primary" @click="handleSubmit">确定</el-button>
        </div>
      </template>
    </el-dialog>
@@ -103,252 +93,246 @@
</template>
<script setup>
import { ref, reactive, computed, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import DynamicTable from '@/components/DynamicTable/index.vue'
  import { ref, reactive, computed, onMounted } from "vue";
  import { ElMessage, ElMessageBox } from "element-plus";
  import DynamicTable from "@/components/DynamicTable/index.vue";
// 响应式数据
const loading = ref(false)
const dialogVisible = ref(false)
const dialogTitle = ref('')
const editIndex = ref(-1)
const selectedRows = ref([])
  // 响应式数据
  const loading = ref(false);
  const dialogVisible = ref(false);
  const dialogTitle = ref("");
  const editIndex = ref(-1);
  const selectedRows = ref([]);
// 搜索表单
const searchForm = reactive({
  department: '',
  name: ''
})
  // 搜索表单
  const searchForm = reactive({
    department: "",
    name: "",
  });
// 表格数据
const tableData = ref([
  {
    id: 1,
    department: '技术部',
    name: '张三',
    employeeId: 'EMP001',
    status: '1',
    level: '2',
    position: '1'
  },
  {
    id: 2,
    department: '人事部',
    name: '李四',
    employeeId: 'EMP002',
    status: '0',
    level: '1',
    position: '2'
  },
  {
    id: 3,
    department: '财务部',
    name: '王五',
    employeeId: 'EMP003',
    status: '1',
    level: '3',
    position: '1'
  }
])
// 字典类型配置
const dictTypes = ref([
  'sys_normal_disable', // 状态字典
  'sys_user_level',     // 级别字典
  'sys_user_position'   // 职位字典
])
// 分页配置
const pagination = reactive({
  current: 1,
  size: 10,
  total: 0
})
// 表单数据
const form = reactive({
  department: '',
  name: '',
  employeeId: '',
  status: '',
  level: '',
  position: ''
})
// 表单验证规则
const rules = {
  department: [
    { required: true, message: '请输入部门', trigger: 'blur' }
  ],
  name: [
    { required: true, message: '请输入姓名', trigger: 'blur' }
  ],
  employeeId: [
    { required: true, message: '请输入工号', trigger: 'blur' }
  ]
}
// 动态表单项
const dynamicFormItems = computed(() => {
  // 这里可以根据字典数据动态生成表单项
  return [
  // 表格数据
  const tableData = ref([
    {
      label: '状态',
      value: 'status',
      options: [
        { label: '启用', value: '1' },
        { label: '禁用', value: '0' }
      ]
      id: 1,
      department: "技术部",
      name: "张三",
      employeeId: "EMP001",
      status: "1",
      level: "2",
      position: "1",
    },
    {
      label: '级别',
      value: 'level',
      options: [
        { label: '初级', value: '1' },
        { label: '中级', value: '2' },
        { label: '高级', value: '3' }
      ]
      id: 2,
      department: "人事部",
      name: "李四",
      employeeId: "EMP002",
      status: "0",
      level: "1",
      position: "2",
    },
    {
      label: '职位',
      value: 'position',
      options: [
        { label: '员工', value: '1' },
        { label: '主管', value: '2' },
        { label: '经理', value: '3' }
      ]
      id: 3,
      department: "财务部",
      name: "王五",
      employeeId: "EMP003",
      status: "1",
      level: "3",
      position: "1",
    },
  ]);
  // 字典类型配置
  const dictTypes = ref([
    "sys_normal_disable", // 状态字典
    "sys_user_level", // 级别字典
    "sys_user_position", // 职位字典
  ]);
  // 分页配置
  const pagination = reactive({
    current: 1,
    size: 10,
    total: 0,
  });
  // 表单数据
  const form = reactive({
    department: "",
    name: "",
    employeeId: "",
    status: "",
    level: "",
    position: "",
  });
  // 表单验证规则
  const rules = {
    department: [{ required: true, message: "请输入部门", trigger: "blur" }],
    name: [{ required: true, message: "请输入姓名", trigger: "blur" }],
    employeeId: [{ required: true, message: "请输入工号", trigger: "blur" }],
  };
  // 动态表单项
  const dynamicFormItems = computed(() => {
    // 这里可以根据字典数据动态生成表单项
    return [
      {
        label: "状态",
        value: "status",
        options: [
          { label: "启用", value: "1" },
          { label: "禁用", value: "0" },
        ],
      },
      {
        label: "级别",
        value: "level",
        options: [
          { label: "初级", value: "1" },
          { label: "中级", value: "2" },
          { label: "高级", value: "3" },
        ],
      },
      {
        label: "职位",
        value: "position",
        options: [
          { label: "员工", value: "1" },
          { label: "主管", value: "2" },
          { label: "经理", value: "3" },
        ],
      },
    ];
  });
  // 组件引用
  const dynamicTableRef = ref(null);
  const formRef = ref(null);
  // 事件处理函数
  const handleSearch = () => {
    // 实现搜索逻辑
    console.log("搜索条件:", searchForm);
    ElMessage.success("搜索功能待实现");
  };
  const handleReset = () => {
    searchForm.department = "";
    searchForm.name = "";
  };
  const handleAdd = () => {
    dialogTitle.value = "新增员工";
    editIndex.value = -1;
    resetForm();
    dialogVisible.value = true;
  };
  const handleEdit = (row, index) => {
    dialogTitle.value = "编辑员工";
    editIndex.value = index;
    Object.assign(form, row);
    dialogVisible.value = true;
  };
  const handleDelete = async (row, index) => {
    try {
      await ElMessageBox.confirm("确定要删除这条记录吗?", "提示", {
        type: "warning",
      });
      tableData.value.splice(index, 1);
      ElMessage.success("删除成功");
    } catch (error) {
      // 用户取消删除
    }
  ]
})
  };
// 组件引用
const dynamicTableRef = ref(null)
const formRef = ref(null)
  const handleSelectionChange = selection => {
    selectedRows.value = selection;
  };
// 事件处理函数
const handleSearch = () => {
  // 实现搜索逻辑
  console.log('搜索条件:', searchForm)
  ElMessage.success('搜索功能待实现')
}
  const handleSelectChange = (row, prop, value) => {
    console.log("选择变化:", row, prop, value);
    // 可以在这里处理数据更新逻辑
  };
const handleReset = () => {
  searchForm.department = ''
  searchForm.name = ''
}
  const handleInputChange = (row, prop, value) => {
    console.log("输入变化:", row, prop, value);
    // 可以在这里处理数据更新逻辑
  };
const handleAdd = () => {
  dialogTitle.value = '新增员工'
  editIndex.value = -1
  resetForm()
  dialogVisible.value = true
}
  const handleSizeChange = size => {
    pagination.size = size;
    // 重新加载数据
  };
const handleEdit = (row, index) => {
  dialogTitle.value = '编辑员工'
  editIndex.value = index
  Object.assign(form, row)
  dialogVisible.value = true
}
  const handleCurrentChange = current => {
    pagination.current = current;
    // 重新加载数据
  };
const handleDelete = async (row, index) => {
  try {
    await ElMessageBox.confirm('确定要删除这条记录吗?', '提示', {
      type: 'warning'
    })
    tableData.value.splice(index, 1)
    ElMessage.success('删除成功')
  } catch (error) {
    // 用户取消删除
  }
}
  const handleSubmit = async () => {
    try {
      await formRef.value.validate();
const handleSelectionChange = (selection) => {
  selectedRows.value = selection
}
const handleSelectChange = (row, prop, value) => {
  console.log('选择变化:', row, prop, value)
  // 可以在这里处理数据更新逻辑
}
const handleInputChange = (row, prop, value) => {
  console.log('输入变化:', row, prop, value)
  // 可以在这里处理数据更新逻辑
}
const handleSizeChange = (size) => {
  pagination.size = size
  // 重新加载数据
}
const handleCurrentChange = (current) => {
  pagination.current = current
  // 重新加载数据
}
const handleSubmit = async () => {
  try {
    await formRef.value.validate()
    if (editIndex.value === -1) {
      // 新增
      const newRow = {
        id: Date.now(),
        ...form
      if (editIndex.value === -1) {
        // 新增
        const newRow = {
          id: Date.now(),
          ...form,
        };
        tableData.value.push(newRow);
        ElMessage.success("新增成功");
      } else {
        // 编辑
        Object.assign(tableData.value[editIndex.value], form);
        ElMessage.success("编辑成功");
      }
      tableData.value.push(newRow)
      ElMessage.success('新增成功')
    } else {
      // 编辑
      Object.assign(tableData.value[editIndex.value], form)
      ElMessage.success('编辑成功')
      dialogVisible.value = false;
    } catch (error) {
      console.error("表单验证失败:", error);
    }
    dialogVisible.value = false
  } catch (error) {
    console.error('表单验证失败:', error)
  }
}
  };
const resetForm = () => {
  Object.assign(form, {
    department: '',
    name: '',
    employeeId: '',
    status: '',
    level: '',
    position: ''
  })
  formRef.value?.resetFields()
}
  const resetForm = () => {
    Object.assign(form, {
      department: "",
      name: "",
      employeeId: "",
      status: "",
      level: "",
      position: "",
    });
    formRef.value?.resetFields();
  };
// 组件挂载时初始化数据
onMounted(() => {
  pagination.total = tableData.value.length
})
  // 组件挂载时初始化数据
  onMounted(() => {
    pagination.total = tableData.value.length;
  });
</script>
<style scoped>
.app-container {
  padding: 20px;
}
  .app-container {
    padding: 20px;
  }
.search-form {
  margin-bottom: 20px;
  padding: 20px;
  background-color: #f5f5f5;
  border-radius: 4px;
}
  .search-form {
    margin-bottom: 20px;
    padding: 20px;
    background-color: #f5f5f5;
    border-radius: 4px;
  }
.table-container {
  background-color: #fff;
  border-radius: 4px;
  padding: 20px;
}
  .table-container {
    background-color: #fff;
    border-radius: 4px;
    padding: 20px;
  }
.dialog-footer {
  text-align: right;
}
  .dialog-footer {
    text-align: right;
  }
</style>