huminmin
昨天 c1657d7fa4e9c9272da960fb1f7fa2595188571c
src/views/example/DynamicTableExample.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,354 @@
<template>
  <div class="app-container">
    <div class="search-form">
      <el-form :inline="true" :model="searchForm">
        <el-form-item label="部门">
          <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-form-item>
        <el-form-item>
          <el-button type="primary" @click="handleSearch">搜索</el-button>
          <el-button @click="handleReset">重置</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"
      />
    </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-form-item>
        <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>
        <!-- åŠ¨æ€è¡¨å•é¡¹ï¼šæ ¹æ®å­—å…¸ç”Ÿæˆ -->
        <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>
        </div>
      </template>
    </el-dialog>
  </div>
</template>
<script setup>
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 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 [
    {
      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 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
      }
      tableData.value.push(newRow)
      ElMessage.success('新增成功')
    } else {
      // ç¼–辑
      Object.assign(tableData.value[editIndex.value], form)
      ElMessage.success('编辑成功')
    }
    dialogVisible.value = false
  } catch (error) {
    console.error('表单验证失败:', error)
  }
}
const resetForm = () => {
  Object.assign(form, {
    department: '',
    name: '',
    employeeId: '',
    status: '',
    level: '',
    position: ''
  })
  formRef.value?.resetFields()
}
// ç»„件挂载时初始化数据
onMounted(() => {
  pagination.total = tableData.value.length
})
</script>
<style scoped>
.app-container {
  padding: 20px;
}
.search-form {
  margin-bottom: 20px;
  padding: 20px;
  background-color: #f5f5f5;
  border-radius: 4px;
}
.table-container {
  background-color: #fff;
  border-radius: 4px;
  padding: 20px;
}
.dialog-footer {
  text-align: right;
}
</style>