Skip to content

🚀 高级功能文档

l-pc-front 项目高级功能深度解析与最佳实践


🔄 路由栈管理器

功能概述

路由栈管理器是项目的核心高级功能之一,它基于 Vuex 实现,用于管理应用的路由历史记录,支持智能返回、前进和路由栈操作,提供了类似浏览器历史记录的功能。

设计理念

  • 持久化存储 - 路由栈信息持久化到 localStorage
  • 智能导航 - 支持基于栈的智能返回和前进
  • 灵活配置 - 可启用/禁用,支持自定义最大栈大小
  • 浏览器兼容 - 兼容浏览器原生导航
  • 性能优化 - 限制栈大小,避免内存占用过大

架构设计

┌─────────────────────────────────────────────────────────┐
│                     路由栈管理器                         │
├─────────────┬─────────────┬─────────────┬───────────────┤
│  Vuex Store │ localStorage│  Vue Router │  应用组件      │
├─────────────┼─────────────┼─────────────┼───────────────┤
│  状态管理   │  持久化存储  │  路由跳转    │  路由导航      │
└─────────────┴─────────────┴─────────────┴───────────────┘

核心实现

状态管理

javascript
const state = {
  stack: loadRouteStackFromStorage(),  // 路由栈数组
  currentIndex: -1,                    // 当前路由索引
  enabled: true,                       // 是否启用
  maxSize: MAX_STACK_SIZE              // 最大栈大小
};

路由记录结构

javascript
const createRouteRecord = (route) => {
  return {
    path: route.path,                  // 路径
    name: route.name,                  // 路由名称
    params: { ...route.params },       // 参数
    query: { ...route.query },         // 查询参数
    hash: route.hash,                  // 哈希值
    fullPath: route.fullPath,          // 完整路径
    meta: { ...route.meta },           // 元信息
    timestamp: Date.now(),             // 时间戳
    id: `${route.fullPath}_${Date.now()}_${Math.random().toString(36).substr(2, 9)}` // 唯一ID
  };
};

核心功能

1. 路由栈操作

推入路由
javascript
// 自动推入当前路由到栈中
this.$store.dispatch('routeStack/pushRoute', this.$route);
弹出路由
javascript
// 从栈中弹出当前路由
this.$store.dispatch('routeStack/popRoute');
清空路由栈
javascript
// 清空整个路由栈
this.$store.dispatch('routeStack/clearStack');

2. 导航功能

返回上一个路由
javascript
// 智能返回上一个路由
this.$store.dispatch('routeStack/goBack', this.$router);
前进到下一个路由
javascript
// 前进到下一个路由
this.$store.dispatch('routeStack/goForward', this.$router);
跳转到指定索引
javascript
// 跳转到栈中指定索引的路由
this.$store.dispatch('routeStack/goToIndex', {
  index: 2,
  router: this.$router
});

3. 查询功能

获取路由栈信息
javascript
// 获取完整路由栈
const stack = this.$store.getters['routeStack/routeStack'];

// 获取当前索引
const currentIndex = this.$store.getters['routeStack/currentIndex'];

// 是否可以返回
const canGoBack = this.$store.getters['routeStack/canGoBack'];

// 是否可以前进
const canGoForward = this.$store.getters['routeStack/canGoForward'];

// 获取上一个路由
const previousRoute = this.$store.getters['routeStack/previousRoute'];

// 获取下一个路由
const nextRoute = this.$store.getters['routeStack/nextRoute'];

4. 配置功能

启用/禁用路由栈
javascript
// 启用路由栈
this.$store.dispatch('routeStack/setEnabled', true);

// 禁用路由栈
this.$store.dispatch('routeStack/setEnabled', false);
设置最大栈大小
javascript
// 设置最大栈大小为 100
this.$store.dispatch('routeStack/setMaxSize', 100);

使用示例

基础使用

javascript
// 在路由守卫中自动管理路由栈
router.afterEach((to) => {
  store.dispatch('routeStack/pushRoute', to);
});

// 在组件中使用
export default {
  computed: {
    canGoBack() {
      return this.$store.getters['routeStack/canGoBack'];
    }
  },
  methods: {
    goBack() {
      this.$store.dispatch('routeStack/goBack', this.$router);
    }
  }
};

智能返回按钮

vue
<template>
  <div class="app-header">
    <el-button 
      v-if="canGoBack" 
      @click="goBack"
      icon="el-icon-back"
    >
      返回
    </el-button>
    <h1 class="title">应用标题</h1>
  </div>
</template>

<script>
export default {
  computed: {
    canGoBack() {
      return this.$store.getters['routeStack/canGoBack'];
    }
  },
  methods: {
    goBack() {
      this.$store.dispatch('routeStack/goBack', this.$router);
    }
  }
};
</script>

路由栈可视化

vue
<template>
  <div class="route-stack-visualizer">
    <h3>路由栈可视化</h3>
    <div class="stack-container">
      <div 
        v-for="(route, index) in routeStack" 
        :key="route.id"
        class="stack-item"
        :class="{ 'current': index === currentIndex }"
      >
        <div class="stack-item-path">{{ route.path }}</div>
        <div class="stack-item-info">
          <span class="index">{{ index }}</span>
          <span class="timestamp">{{ formatTime(route.timestamp) }}</span>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  computed: {
    routeStack() {
      return this.$store.getters['routeStack/routeStack'];
    },
    currentIndex() {
      return this.$store.getters['routeStack/currentIndex'];
    }
  },
  methods: {
    formatTime(timestamp) {
      return new Date(timestamp).toLocaleString();
    }
  }
};
</script>

最佳实践

  1. 路由守卫集成

    • router.afterEach 守卫中自动推入路由到栈中
    • 确保路由栈与实际导航同步
  2. 状态持久化

    • 利用 localStorage 实现路由栈的持久化
    • 页面刷新后可恢复路由栈状态
  3. 智能返回逻辑

    • 优先使用路由栈返回,避免浏览器历史记录混乱
    • 提供清晰的返回按钮状态反馈
  4. 性能优化

    • 合理设置最大栈大小,避免内存占用过大
    • 定期清理过期路由记录
  5. 错误处理

    • 处理 localStorage 读写失败的情况
    • 确保路由栈操作的原子性

配置与依赖

依赖项

  • Vuex - 状态管理
  • Vue Router - 路由管理

配置项

javascript
const MAX_STACK_SIZE = 50; // 最大栈大小
const STORAGE_KEY = 'route_stack_history'; // localStorage 存储键名

🧩 组件化CRUD最佳实践

概述

组件化CRUD是项目的核心设计理念之一,通过标准化的组件接口,实现了数据的增删改查功能的快速开发和复用。

核心组件

组件名称功能说明文件路径
list.vue数据列表展示src/components/common/list.vue
detail.vue数据详情展示src/components/common/detail.vue
add.vue数据新增src/components/common/add.vue
update.vue数据编辑src/components/common/update.vue

设计理念

  1. 标准化接口 - 统一的组件配置格式
  2. 高内聚低耦合 - 组件内部逻辑封装,外部配置简单
  3. 可扩展性 - 支持自定义字段、自定义渲染、自定义操作
  4. 易用性 - 简单的配置即可实现复杂功能
  5. 灵活性 - 支持多种数据来源和展示方式

配置格式

1. 列表组件配置

javascript
const listConfig = {
  serviceName: 'srvuser_list_select', // 服务名称
  fields: [                           // 字段配置
    {
      key: 'name',                    // 字段名
      label: '姓名',                  // 显示标签
      width: 120,                    // 列宽
      sortable: true,                // 是否可排序
      formatter: (value) => {},      // 自定义格式化
      type: 'text'                   // 字段类型
    }
  ],
  actions: [                          // 操作按钮配置
    {
      label: '编辑',                  // 按钮文本
      action: 'edit',                // 操作标识
      type: 'primary',               // 按钮类型
      permission: 'user:edit',       // 权限标识
      icon: 'el-icon-edit'           // 图标
    }
  ],
  filters: [                          // 筛选条件配置
    {
      key: 'name',                   // 字段名
      label: '姓名',                 // 显示标签
      type: 'text'                  // 筛选类型
    }
  ],
  pagination: {
    pageSize: 20,                   // 每页条数
    showTotal: true                 // 是否显示总数
  },
  selectable: true,                  // 是否可选择
  treeMode: false                    // 是否树形模式
};

2. 详情组件配置

javascript
const detailConfig = {
  serviceName: 'srvuser_detail_select', // 服务名称
  fields: [                           // 字段配置
    {
      label: '基本信息',               // 分组标签
      type: 'group',                  // 字段类型
      children: [                     // 子字段
        {
          key: 'name',                // 字段名
          label: '姓名',              // 显示标签
          type: 'text'               // 字段类型
        }
      ]
    }
  ],
  actions: [                          // 操作按钮
    {
      label: '编辑',                  // 按钮文本
      action: 'edit',                // 操作标识
      type: 'primary'                // 按钮类型
    }
  ],
  childConfigs: [                     // 关联子表配置
    {
      title: '关联数据',              // 子表标题
      serviceName: 'srvuser_related_select', // 子表服务名称
      parentKey: 'userId',           // 父表关联字段
      childKey: 'userId',            // 子表关联字段
      fields: []                    // 子表字段配置
    }
  ]
};

3. 表单组件配置

javascript
const formConfig = {
  serviceName: 'srvuser_add',         // 服务名称
  fields: [                           // 字段配置
    {
      key: 'name',                    // 字段名
      label: '姓名',                  // 显示标签
      type: 'text',                  // 字段类型
      required: true,                // 是否必填
      placeholder: '请输入姓名',      // 占位符
      span: 12,                     // 栅格宽度
      defaultValue: '',             // 默认值
      rules: [                      // 验证规则
        { required: true, message: '请输入姓名', trigger: 'blur' }
      ]
    }
  ],
  actions: [                          // 操作按钮
    {
      label: '保存',                  // 按钮文本
      action: 'submit',              // 操作标识
      type: 'primary'                // 按钮类型
    },
    {
      label: '取消',                  // 按钮文本
      action: 'cancel',              // 操作标识
      type: 'info'                   // 按钮类型
    }
  ]
};

使用示例

1. 完整的CRUD页面

vue
<template>
  <div class="crud-page">
    <!-- 列表组件 -->
    <list 
      v-if="mode === 'list'" 
      :service-name="listConfig.serviceName"
      :fields="listConfig.fields"
      :actions="listConfig.actions"
      :filters="listConfig.filters"
      :pagination="listConfig.pagination"
      :selectable="listConfig.selectable"
      @row-click="handleRowClick"
      @action-click="handleListAction"
    />
    
    <!-- 详情组件 -->
    <detail 
      v-else-if="mode === 'detail'"
      :service-name="detailConfig.serviceName"
      :id="currentId"
      :fields="detailConfig.fields"
      :actions="detailConfig.actions"
      :child-configs="detailConfig.childConfigs"
      @action-clicked="handleDetailAction"
    />
    
    <!-- 新增组件 -->
    <add 
      v-else-if="mode === 'add'"
      :service-name="formConfig.serviceName"
      :fields="formConfig.fields"
      :actions="formConfig.actions"
      @success="handleAddSuccess"
      @cancel="handleCancel"
    />
    
    <!-- 编辑组件 -->
    <update 
      v-else-if="mode === 'update'"
      :service-name="formConfig.serviceName"
      :id="currentId"
      :fields="formConfig.fields"
      :actions="formConfig.actions"
      @success="handleUpdateSuccess"
      @cancel="handleCancel"
    />
  </div>
</template>

<script>
import { ref, computed } from 'vue';
import list from '@/components/common/list.vue';
import detail from '@/components/common/detail.vue';
import add from '@/components/common/add.vue';
import update from '@/components/common/update.vue';

export default {
  components: {
    list,
    detail,
    add,
    update
  },
  setup() {
    const mode = ref('list'); // list, detail, add, update
    const currentId = ref(null);
    
    // 列表配置
    const listConfig = {
      serviceName: 'srvuser_list_select',
      fields: [
        { key: 'name', label: '姓名', width: 120 },
        { key: 'email', label: '邮箱', width: 200 },
        { key: 'phone', label: '手机号', width: 150 },
        { key: 'status', label: '状态', width: 100 }
      ],
      actions: [
        { label: '详情', action: 'detail', type: 'info' },
        { label: '编辑', action: 'edit', type: 'primary' },
        { label: '删除', action: 'delete', type: 'danger' }
      ],
      filters: [
        { key: 'name', label: '姓名', type: 'text' },
        { key: 'status', label: '状态', type: 'select', options: [{ label: '启用', value: 1 }, { label: '禁用', value: 0 }] }
      ],
      pagination: {
        pageSize: 20,
        showTotal: true
      },
      selectable: true
    };
    
    // 详情配置
    const detailConfig = {
      serviceName: 'srvuser_detail_select',
      fields: [
        { 
          label: '基本信息', 
          type: 'group',
          children: [
            { key: 'name', label: '姓名', type: 'text' },
            { key: 'email', label: '邮箱', type: 'email' },
            { key: 'phone', label: '手机号', type: 'text' },
            { key: 'status', label: '状态', type: 'status', mapping: { 1: '启用', 0: '禁用' } }
          ]
        }
      ],
      actions: [
        { label: '编辑', action: 'edit', type: 'primary' },
        { label: '返回', action: 'back', type: 'info' }
      ]
    };
    
    // 表单配置
    const formConfig = {
      serviceName: 'srvuser_add',
      fields: [
        { 
          label: '姓名', 
          key: 'name', 
          type: 'text',
          required: true,
          placeholder: '请输入姓名',
          span: 12
        },
        { 
          label: '邮箱', 
          key: 'email', 
          type: 'email',
          required: true,
          placeholder: '请输入邮箱',
          span: 12
        },
        { 
          label: '手机号', 
          key: 'phone', 
          type: 'text',
          required: true,
          placeholder: '请输入手机号',
          span: 12,
          pattern: /^1[3-9]\d{9}$/,
          message: '手机号格式不正确'
        },
        { 
          label: '状态', 
          key: 'status', 
          type: 'radio',
          required: true,
          options: [{ label: '启用', value: 1 }, { label: '禁用', value: 0 }],
          defaultValue: 1,
          span: 12
        }
      ],
      actions: [
        { label: '保存', type: 'primary', action: 'submit' },
        { label: '保存并继续', type: 'success', action: 'submitAndContinue' },
        { label: '取消', type: 'info', action: 'cancel' }
      ]
    };
    
    // 事件处理
    const handleRowClick = (row) => {
      currentId.value = row.id;
      mode.value = 'detail';
    };
    
    const handleListAction = (action, row) => {
      switch (action) {
        case 'detail':
          currentId.value = row.id;
          mode.value = 'detail';
          break;
        case 'edit':
          currentId.value = row.id;
          mode.value = 'update';
          break;
        case 'delete':
          handleDelete(row);
          break;
      }
    };
    
    const handleDetailAction = (action) => {
      if (action === 'edit') {
        mode.value = 'update';
      } else if (action === 'back') {
        mode.value = 'list';
      }
    };
    
    const handleAddSuccess = (data) => {
      console.log('新增成功:', data);
      mode.value = 'list';
    };
    
    const handleUpdateSuccess = (data) => {
      console.log('更新成功:', data);
      mode.value = 'list';
    };
    
    const handleDelete = (row) => {
      // 删除逻辑
      console.log('删除:', row);
    };
    
    const handleCancel = () => {
      mode.value = 'list';
    };
    
    return {
      mode,
      currentId,
      listConfig,
      detailConfig,
      formConfig,
      handleRowClick,
      handleListAction,
      handleDetailAction,
      handleAddSuccess,
      handleUpdateSuccess,
      handleDelete,
      handleCancel
    };
  }
};
</script>

最佳实践

1. 配置分离

将组件配置与业务逻辑分离,便于维护和复用。

javascript
// configs/user.js
export const userListConfig = {
  serviceName: 'srvuser_list_select',
  fields: [],
  actions: []
};

export const userFormConfig = {
  serviceName: 'srvuser_add',
  fields: [],
  actions: []
};

// 使用
import { userListConfig, userFormConfig } from '@/configs/user';

2. 动态配置

根据业务需求动态生成配置。

javascript
const getListConfig = (isAdmin) => {
  const baseConfig = {
    serviceName: 'srvuser_list_select',
    fields: [
      { key: 'name', label: '姓名' },
      { key: 'email', label: '邮箱' }
    ]
  };
  
  // 管理员可以看到更多字段和操作
  if (isAdmin) {
    baseConfig.fields.push({ key: 'status', label: '状态' });
    baseConfig.actions.push({ label: '禁用', action: 'disable', type: 'warning' });
  }
  
  return baseConfig;
};

3. 自定义渲染

利用组件的自定义渲染功能,实现复杂的字段展示。

javascript
const listConfig = {
  fields: [
    {
      key: 'status',
      label: '状态',
      type: 'custom',
      render: (h, row) => {
        return h('el-tag', {
          props: {
            type: row.status === 1 ? 'success' : 'danger'
          }
        }, row.status === 1 ? '启用' : '禁用');
      }
    }
  ]
};

4. 权限控制

结合权限系统,实现基于角色的字段和操作显示控制。

javascript
const listConfig = {
  actions: [
    {
      label: '编辑',
      action: 'edit',
      type: 'primary',
      permission: 'user:edit', // 权限标识
      visible: () => {
        return this.$store.getters.hasPermission('user:edit');
      }
    }
  ]
};

5. 性能优化

  • 合理使用缓存,避免重复请求
  • 对于大数据量,使用分页和虚拟滚动
  • 合理设置组件的 lazy 属性,延迟加载组件

6. 错误处理

  • 统一处理组件的错误事件
  • 提供友好的错误提示
  • 实现重试机制

扩展与定制

1. 自定义组件

继承基础组件,实现自定义功能。

javascript
import BaseList from '@/components/common/list.vue';

export default {
  extends: BaseList,
  methods: {
    // 覆盖父组件的方法
    fetchData() {
      // 自定义数据获取逻辑
    }
  }
};

2. 混合逻辑

使用 mixin 复用组件逻辑。

javascript
import formMixin from '@/components/mixin/formMixin';

export default {
  mixins: [formMixin],
  methods: {
    // 可以使用 formMixin 中的方法
    submitForm() {
      this.validateForm().then(() => {
        // 提交逻辑
      });
    }
  }
};

3. 插件扩展

通过插件机制,扩展组件功能。

javascript
// 注册全局组件插件
const crudPlugin = {
  install(Vue) {
    Vue.component('crud-list', () => import('@/components/common/list.vue'));
    Vue.component('crud-detail', () => import('@/components/common/detail.vue'));
    Vue.component('crud-add', () => import('@/components/common/add.vue'));
    Vue.component('crud-update', () => import('@/components/common/update.vue'));
  }
};

Vue.use(crudPlugin);

性能优化

  1. 数据缓存 - 对于频繁使用的数据,进行缓存处理
  2. 懒加载 - 组件和数据的懒加载
  3. 虚拟滚动 - 大数据量列表使用虚拟滚动
  4. 减少重渲染 - 合理使用 computed 和 watch
  5. 批量操作 - 支持批量数据处理

测试与调试

  1. 单元测试 - 组件的单元测试
  2. 集成测试 - 组件间集成测试
  3. 调试工具 - 使用 Vue DevTools 进行调试
  4. 日志记录 - 关键操作的日志记录

🎯 低代码平台架构设计

概述

低代码平台是项目的核心功能之一,支持可视化页面构建,用户可以通过拖拽和配置快速创建业务页面。

核心功能

  • 可视化编辑器 - 拖拽式页面构建
  • 组件库 - 丰富的组件支持
  • 属性配置 - 可视化属性配置
  • 实时预览 - 实时预览页面效果
  • 代码生成 - 自动生成代码
  • 多端适配 - 支持移动端和PC端

架构设计

┌─────────────────────────────────────────────────────────┐
│                     低代码平台                          │
├─────────────┬─────────────┬─────────────┬───────────────┤
│  编辑器核心   │  组件库      │  属性配置器   │  页面渲染器   │
├─────────────┼─────────────┼─────────────┼───────────────┤
│  拖拽逻辑    │  组件管理    │  属性面板    │  页面生成     │
└─────────────┴─────────────┴─────────────┴───────────────┘

技术栈

  • Vue 2.7 - 前端框架
  • Element UI - UI组件库
  • Vuex - 状态管理
  • Vue Router - 路由管理
  • ECharts - 图表库

核心模块

1. 编辑器核心

功能: 实现组件的拖拽、缩放、旋转等操作 主要组件: src/pages/lowcode/components/editor/index.vue

2. 组件库

功能: 提供丰富的组件供用户选择和使用 主要组件类型:

  • 基础组件 - 文本、图片、按钮等
  • 布局组件 - 容器、网格等
  • 表单组件 - 输入框、选择器等
  • 图表组件 - 柱状图、折线图等
  • 高级组件 - 地图、富文本等

3. 属性配置器

功能: 可视化配置组件的属性 主要特性:

  • 动态生成属性面板
  • 支持多种属性类型
  • 实时更新组件

4. 页面渲染器

功能: 根据配置渲染页面 主要特性:

  • 支持PC端和移动端
  • 实时渲染
  • 高性能

工作流程

  1. 组件拖拽 - 用户从组件库拖拽组件到画布
  2. 属性配置 - 在属性面板配置组件属性
  3. 实时预览 - 实时查看页面效果
  4. 页面保存 - 保存页面配置
  5. 代码生成 - 生成可运行的代码
  6. 部署发布 - 部署到生产环境

配置格式

页面配置

json
{
  "id": "page_001",
  "name": "测试页面",
  "layout": "grid",
  "width": 1920,
  "height": 1080,
  "components": [
    {
      "id": "comp_001",
      "type": "text",
      "props": {
        "text": "Hello World",
        "fontSize": 24,
        "color": "#333"
      },
      "style": {
        "left": 100,
        "top": 100,
        "width": 200,
        "height": 50
      }
    }
  ]
}

最佳实践

  1. 组件设计

    • 组件职责单一
    • 接口标准化
    • 支持自定义属性
  2. 性能优化

    • 组件懒加载
    • 虚拟DOM
    • 合理使用缓存
  3. 用户体验

    • 直观的拖拽体验
    • 实时预览
    • 友好的错误提示
  4. 扩展性

    • 支持第三方组件集成
    • 插件机制
    • 自定义模板

部署与发布

  1. 本地开发 - 在本地进行页面设计和调试
  2. 测试环境 - 部署到测试环境进行测试
  3. 生产环境 - 部署到生产环境
  4. 版本管理 - 实现页面的版本控制

📝 总结

本文档详细介绍了项目的高级功能,包括路由栈管理器、组件化CRUD最佳实践和低代码平台架构设计。这些功能是项目的核心竞争力,通过合理使用这些功能,可以提高开发效率,降低维护成本,实现快速迭代和扩展。

关键优势

  1. 路由栈管理器 - 提供了智能的路由管理,提升了用户体验
  2. 组件化CRUD - 标准化的组件接口,实现了代码的复用和快速开发
  3. 低代码平台 - 可视化页面构建,降低了开发门槛

未来展望

  1. 微前端架构 - 支持微前端,实现模块的独立部署和运行
  2. Serverless集成 - 与Serverless架构集成,实现前后端一体化开发
  3. AI辅助开发 - 利用AI技术,实现智能代码生成和优化
  4. 更好的移动端支持 - 进一步优化移动端体验
  5. 增强的低代码能力 - 支持更复杂的业务场景

通过不断优化和扩展这些高级功能,项目将能够更好地满足用户的需求,提供更好的用户体验和开发体验。


文档维护: l-pc-front 开发组
最后更新: 2025-12-20

最近更新