COMPONENTS_USAGE.md 16 KB

通用组件使用指南

本文档介绍5个新创建的通用组件的使用方法和API。

🔧 A) XtStickyActionBar - 底部粘性操作栏

功能描述

底部固定的操作栏,显示状态信息和操作按钮,支持响应式设计和明暗主题。

Props

参数 类型 默认值 说明
dirtyCount Number 0 变更项数量
errorCount Number 0 错误项数量
loading Object {} 加载状态对象
showProgress Boolean false 是否显示进度条
progressPercent Number 0 进度百分比(0-100)

Events

事件名 参数 说明
save - 保存草稿
test - 测试全部
publish - 发布
rollback - 回滚
reset - 重置变更
export - 导出配置

使用示例

<template>
  <div>
    <!-- 页面内容 -->
    <div class="page-content">
      <!-- ... -->
    </div>
    
    <!-- 底部操作栏 -->
    <XtStickyActionBar
      :dirty-count="formChanges.length"
      :error-count="validationErrors.length"
      :loading="actionLoading"
      :show-progress="isProcessing"
      :progress-percent="processPercent"
      @save="handleSaveDraft"
      @test="handleTestAll"
      @publish="handlePublish"
      @rollback="handleRollback"
    />
  </div>
</template>

<script>
export default {
  data() {
    return {
      formChanges: [],
      validationErrors: [],
      actionLoading: {
        save: false,
        test: false,
        publish: false,
        rollback: false
      },
      isProcessing: false,
      processPercent: 0
    }
  },
  
  methods: {
    handleSaveDraft() {
      this.actionLoading.save = true
      // 保存逻辑
    },
    
    handleTestAll() {
      this.actionLoading.test = true
      // 测试逻辑
    },
    
    handlePublish() {
      if (this.validationErrors.length > 0) {
        this.$message.error('请先修复所有错误')
        return
      }
      this.actionLoading.publish = true
      // 发布逻辑
    }
  }
}
</script>

📋 B) XtGroupedFormCard - 分组表单卡片

功能描述

可折叠的分组表单卡片,支持自定义操作按钮和过渡动画。

Props

参数 类型 默认值 说明
title String - 卡片标题(必填)
desc String '' 卡片描述
collapsible Boolean true 是否可折叠
defaultCollapsed Boolean false 默认是否折叠

Events

事件名 参数 说明
test - 测试按钮点击
reset - 重置按钮点击
toggle collapsed 折叠状态变化

Slots

插槽名 说明
default 表单内容区域
actions 自定义右上角操作按钮

使用示例

<template>
  <div class="form-container">
    <XtGroupedFormCard
      title="数据库配置"
      desc="配置数据库连接参数"
      :collapsible="true"
      :default-collapsed="false"
      @test="testDbConnection"
      @reset="resetDbConfig"
      @toggle="handleToggle"
    >
      <!-- 自定义操作按钮 -->
      <template #actions>
        <el-button
          type="text"
          size="small"
          icon="el-icon-connection"
          @click="testConnection"
        >
          测试连接
        </el-button>
      </template>
      
      <!-- 表单内容 -->
      <el-form :model="dbConfig" label-width="120px">
        <el-form-item label="主机地址">
          <el-input v-model="dbConfig.host" placeholder="localhost" />
        </el-form-item>
        
        <el-form-item label="端口">
          <el-input v-model="dbConfig.port" placeholder="3306" />
        </el-form-item>
        
        <el-form-item label="数据库名">
          <el-input v-model="dbConfig.database" placeholder="database_name" />
        </el-form-item>
        
        <!-- 表单分组 -->
        <div class="form-group">
          <div class="form-group-title">认证信息</div>
          <el-form-item label="用户名">
            <el-input v-model="dbConfig.username" />
          </el-form-item>
          <el-form-item label="密码">
            <el-input v-model="dbConfig.password" type="password" show-password />
          </el-form-item>
        </div>
      </el-form>
    </XtGroupedFormCard>
  </div>
</template>

<script>
export default {
  data() {
    return {
      dbConfig: {
        host: '',
        port: '',
        database: '',
        username: '',
        password: ''
      }
    }
  },
  
  methods: {
    testDbConnection() {
      console.log('测试数据库连接')
    },
    
    resetDbConfig() {
      this.dbConfig = {
        host: '',
        port: '',
        database: '',
        username: '',
        password: ''
      }
    },
    
    handleToggle(collapsed) {
      console.log('折叠状态:', collapsed)
    }
  }
}
</script>

🔗 C) XtTestConnectionDrawer - 测试连接抽屉

功能描述

右侧抽屉展示测试连接的时间轴日志,支持重新测试和日志管理。

Props

参数 类型 默认值 说明
visible Boolean false 是否显示抽屉
title String '连接测试' 抽屉标题
logs Array [] 测试日志数组
loading Boolean false 加载状态

Events

事件名 参数 说明
close - 关闭抽屉
retest - 重新测试
clear-logs - 清空日志

日志数据格式

{
  ts: 1640995200000,           // 时间戳
  step: '连接数据库',           // 步骤名称
  status: 'ok',                // 状态: 'ok'|'warn'|'fail'
  cost: 120,                   // 耗时(ms)
  tip: '连接成功',             // 提示信息
  details: '详细日志信息...'    // 详细信息(可选)
}

使用示例

<template>
  <div>
    <el-button @click="showTestDrawer = true">测试连接</el-button>
    
    <XtTestConnectionDrawer
      :visible="showTestDrawer"
      title="Redis 连接测试"
      :logs="testLogs"
      :loading="testing"
      @close="showTestDrawer = false"
      @retest="startConnectionTest"
      @clear-logs="clearTestLogs"
    />
  </div>
</template>

<script>
export default {
  data() {
    return {
      showTestDrawer: false,
      testing: false,
      testLogs: [
        {
          ts: Date.now() - 5000,
          step: '解析连接地址',
          status: 'ok',
          cost: 10,
          tip: '地址解析成功: redis://localhost:6379'
        },
        {
          ts: Date.now() - 4000,
          step: '建立TCP连接',
          status: 'ok',
          cost: 150,
          tip: 'TCP连接建立成功'
        },
        {
          ts: Date.now() - 3000,
          step: '身份认证',
          status: 'warn',
          cost: 200,
          tip: '未配置密码,使用默认认证'
        },
        {
          ts: Date.now() - 2000,
          step: '执行PING命令',
          status: 'ok',
          cost: 5,
          tip: '服务器响应: PONG'
        }
      ]
    }
  },
  
  methods: {
    async startConnectionTest() {
      this.testing = true
      this.testLogs = []
      
      try {
        // 模拟测试步骤
        await this.runTestStep('连接服务器', 100)
        await this.runTestStep('验证权限', 200)
        await this.runTestStep('测试读写', 150)
        
        this.$message.success('连接测试完成')
      } catch (error) {
        this.$message.error('连接测试失败')
      } finally {
        this.testing = false
      }
    },
    
    async runTestStep(stepName, duration) {
      const startTime = Date.now()
      
      // 模拟异步操作
      await new Promise(resolve => setTimeout(resolve, duration))
      
      const cost = Date.now() - startTime
      const log = {
        ts: Date.now(),
        step: stepName,
        status: Math.random() > 0.8 ? 'warn' : 'ok',
        cost,
        tip: `${stepName}完成,耗时${cost}ms`
      }
      
      this.testLogs.push(log)
    },
    
    clearTestLogs() {
      this.testLogs = []
    }
  }
}
</script>

📊 D) XtDiffPublishDialog - 差异发布对话框

功能描述

展示配置变更的对比对话框,支持选择性发布和搜索过滤。

Props

参数 类型 默认值 说明
visible Boolean false 是否显示对话框
diffs Array [] 差异数据数组
loading Boolean false 加载状态
publishing Boolean false 发布状态

Events

事件名 参数 说明
confirm selectedKeys 确认发布,返回选中的key数组
cancel - 取消发布

差异数据格式

{
  key: 'database.host',        // 配置键
  name: '数据库主机',          // 显示名称
  path: 'config.database',     // 配置路径
  oldValue: 'localhost',       // 原值
  newValue: '192.168.1.100',   // 新值
  isChanged: true,             // 是否变更
  isNew: false,                // 是否新增
  isDeleted: false,            // 是否删除
  description: '主机地址变更'   // 变更说明
}

使用示例

<template>
  <div>
    <el-button @click="showPublishDialog = true">发布配置</el-button>
    
    <XtDiffPublishDialog
      :visible="showPublishDialog"
      :diffs="configDiffs"
      :loading="loadingDiffs"
      :publishing="publishingConfig"
      @confirm="handlePublishConfirm"
      @cancel="showPublishDialog = false"
    />
  </div>
</template>

<script>
export default {
  data() {
    return {
      showPublishDialog: false,
      loadingDiffs: false,
      publishingConfig: false,
      configDiffs: [
        {
          key: 'database.host',
          name: '数据库主机',
          path: 'config.database',
          oldValue: 'localhost',
          newValue: '192.168.1.100',
          isChanged: true,
          isNew: false,
          isDeleted: false,
          description: '切换到生产环境数据库'
        },
        {
          key: 'redis.port',
          name: 'Redis端口',
          path: 'config.redis',
          oldValue: 6379,
          newValue: 6380,
          isChanged: true,
          isNew: false,
          isDeleted: false,
          description: '避免端口冲突'
        },
        {
          key: 'app.debug',
          name: '调试模式',
          path: 'config.app',
          oldValue: true,
          newValue: null,
          isChanged: false,
          isNew: false,
          isDeleted: true,
          description: '生产环境关闭调试'
        }
      ]
    }
  },
  
  methods: {
    async handlePublishConfirm(selectedKeys) {
      this.publishingConfig = true
      
      try {
        // 发布选中的配置项
        await this.publishConfigs(selectedKeys)
        
        this.$message.success(`成功发布 ${selectedKeys.length} 项配置`)
        this.showPublishDialog = false
        
        // 刷新配置列表
        this.loadConfigs()
      } catch (error) {
        this.$message.error('发布失败: ' + error.message)
      } finally {
        this.publishingConfig = false
      }
    },
    
    async publishConfigs(keys) {
      // 模拟发布API调用
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          if (Math.random() > 0.1) {
            resolve()
          } else {
            reject(new Error('网络错误'))
          }
        }, 2000)
      })
    }
  }
}
</script>

📈 E) XtRightSummaryPanel - 右侧摘要面板

功能描述

右侧固定的摘要面板,显示统计信息、配置项状态和快速操作。

Props

参数 类型 默认值 说明
stats Object {} 统计数据对象
items Array [] 配置项数组
loading Boolean false 加载状态
activeItemKey String '' 当前激活的配置项key

Events

事件名 参数 说明
item-click item 配置项点击
publish-changes - 发布变更
fix-risks - 修复风险
test-all - 重新测试

统计数据格式

{
  changed: 5,              // 变更数量
  passed: 12,              // 通过数量
  risk: 2,                 // 风险数量
  lastTestAt: 1640995200000 // 最后测试时间
}

配置项数据格式

{
  key: 'database.host',           // 配置键
  name: '数据库主机',             // 显示名称
  path: 'config.database',        // 配置路径
  group: 'Database',              // 分组
  status: 'passed',               // 状态: 'passed'|'risk'|'pending'|'changed'
  isChanged: false                // 是否变更
}

使用示例

<template>
  <div class="config-page">
    <!-- 主内容区域 -->
    <div class="main-content">
      <!-- 配置表单等内容 -->
    </div>
    
    <!-- 右侧摘要面板 -->
    <XtRightSummaryPanel
      :stats="configStats"
      :items="configItems"
      :loading="loadingStats"
      :active-item-key="activeConfigKey"
      @item-click="handleItemClick"
      @publish-changes="handlePublishChanges"
      @fix-risks="handleFixRisks"
      @test-all="handleTestAll"
    />
  </div>
</template>

<script>
export default {
  data() {
    return {
      loadingStats: false,
      activeConfigKey: '',
      configStats: {
        changed: 3,
        passed: 15,
        risk: 1,
        lastTestAt: Date.now() - 300000 // 5分钟前
      },
      configItems: [
        {
          key: 'database.host',
          name: '数据库主机',
          path: 'config.database',
          group: 'Database',
          status: 'changed',
          isChanged: true
        },
        {
          key: 'redis.port',
          name: 'Redis端口',
          path: 'config.redis',
          group: 'Cache',
          status: 'passed',
          isChanged: false
        },
        {
          key: 'app.secret',
          name: '应用密钥',
          path: 'config.app',
          group: 'Security',
          status: 'risk',
          isChanged: false
        }
      ]
    }
  },
  
  methods: {
    handleItemClick(item) {
      this.activeConfigKey = item.key
      // 跳转到对应的配置项
      this.scrollToConfigItem(item.key)
    },
    
    handlePublishChanges() {
      // 打开发布对话框
      this.showPublishDialog = true
    },
    
    handleFixRisks() {
      // 处理风险配置项
      const riskItems = this.configItems.filter(item => item.status === 'risk')
      this.showRiskFixDialog(riskItems)
    },
    
    handleTestAll() {
      // 重新测试所有配置
      this.runFullTest()
    },
    
    scrollToConfigItem(key) {
      const element = document.getElementById(`config-${key}`)
      if (element) {
        element.scrollIntoView({ behavior: 'smooth' })
      }
    }
  }
}
</script>

<style lang="scss" scoped>
.config-page {
  display: flex;
  height: 100vh;

  .main-content {
    flex: 1;
    overflow-y: auto;
    padding: var(--spacing-6);
  }
}
</style>

🎨 主题适配

所有组件都完全支持明暗主题切换,使用了设计令牌系统中的颜色变量。组件会自动响应主题变化,无需额外配置。

📱 响应式设计

所有组件都内置了响应式设计支持:

  • 移动端优化:在小屏幕设备上自动调整布局
  • 触摸友好:按钮和交互元素针对触摸操作优化
  • 自适应尺寸:根据容器大小自动调整组件尺寸

🔧 自定义样式

如需自定义组件样式,可以通过以下方式:

  1. 使用设计令牌:修改CSS变量来调整主题色彩
  2. CSS类覆盖:使用更高优先级的CSS类覆盖默认样式
  3. 插槽定制:利用组件提供的插槽来自定义内容

🚀 性能优化

  • 虚拟滚动:大列表组件支持虚拟滚动
  • 懒加载:按需加载数据和组件
  • 防抖节流:搜索和频繁操作使用防抖节流
  • 内存管理:组件销毁时正确清理事件监听器

📞 技术支持

如有任何问题或建议,请联系前端开发团队。

Happy Coding! 🎉