行业包文档管理 行业包文档管理
首页
  • 系统快速上手
  • Git分支管理规则及协作流程说明
  • 系统账号密码说明
  • 架构说明

    • 系统整体架构说明
    • QMS-SPC系统架构说明
  • 后端基础类库说明
  • PC端前端所有组件说明 (opens new window)
  • 数据模型设计与说明
  • 后端新建微服务配置
  • 后端华为OpenApis开发
  • 事务集成
  • PC端前端从0开始

    • 本地部署运行
    • 创建前端工程
    • PC端组件库安装使用
    • 按钮权限基础包
  • 移动端前端从0开始

    • 移动端打包APK
    • 移动端公共组件
    • 移动端公共库
  • 前端公共

    • 前端整体架构
    • 前端注意事项
  • 公有云部署流程
  • iDME私有化部署流程
  • 许可授权流程
  • 各方案推荐配置清单
  • PC端前端二开流程
  • 移动端底座二开流程
  • 更新日志及规范规范
常见问题
Source (opens new window)
首页
  • 系统快速上手
  • Git分支管理规则及协作流程说明
  • 系统账号密码说明
  • 架构说明

    • 系统整体架构说明
    • QMS-SPC系统架构说明
  • 后端基础类库说明
  • PC端前端所有组件说明 (opens new window)
  • 数据模型设计与说明
  • 后端新建微服务配置
  • 后端华为OpenApis开发
  • 事务集成
  • PC端前端从0开始

    • 本地部署运行
    • 创建前端工程
    • PC端组件库安装使用
    • 按钮权限基础包
  • 移动端前端从0开始

    • 移动端打包APK
    • 移动端公共组件
    • 移动端公共库
  • 前端公共

    • 前端整体架构
    • 前端注意事项
  • 公有云部署流程
  • iDME私有化部署流程
  • 许可授权流程
  • 各方案推荐配置清单
  • PC端前端二开流程
  • 移动端底座二开流程
  • 更新日志及规范规范
常见问题
Source (opens new window)
  • PC端前端二开流程

    • 一、引言
      • 背景介绍
      • 适用人员
    • 二、环境准备
      • 技术栈
      • 环境配置
      • 开发工具
      • 二开实现
    • 三、二次开发框架概览
      • 框架架构
      • 核心组件
      • SearchForm-查询表单
      • ButtonGroup-按钮组
      • Table-表格
      • Form-表单
      • Tabs-多页签
      • LeftTree-左侧树
    • 四、工具包API概览
      • 模型
      • modelProps
      • modelEmits
      • modelState
      • modelConfig
      • 方法
      • createPageContext-创建页面变量
      • setFormItemListOp-处理formItemList数据
      • setButtonListOp-处理buttonList数据
      • setColumnConfigOp-处理columnConfig数据
      • setTabItemsOp-处理tabItems数据
    • 五、二次开发流程
      • 业务开发人员
      • 二开交付人员
    • 六、常见问题与解决方案
      • 兼容性问题
      • 性能优化
      • 错误排查
      • 1. 包入口文件不正确
      • 2. 本地开发时使用insert会插入多次表单项、按钮、表格列等
      • 3. 使用setColumnConfigOp.insert向表格插入列,插入位置不正确
      • 4. 在配置customSetup时,无法使用$methods
      • 5. 多处引用同一个业务组件并进行二开时,组件之间配置互相干扰、污染
  • 进阶扩展
SIE-DME Group
2024-10-21
目录

PC端前端二开流程

  • 一、引言
    • 背景介绍
    • 适用人员
  • 二、环境准备
    • 技术栈
    • 开发工具
    • 二开实现
  • 三、二次开发框架概览
    • 框架架构
    • 核心组件
  • 四、工具包API概览
    • 模型
    • 方法
  • 五、二次开发流程
    • 业务开发人员
    • 二开交付人员
  • 六、常见问题与解决方案
    • 兼容性问题
    • 性能优化
    • 错误排查

# PC端前端二开流程

# 一、引言

# 背景介绍

  • 在PC端行业包的的标品功能开发时,会沉淀很多通用的行业包标准功能。在实际的项目交付时,会经常需要一定程度的根据项目进行二次开发,如果复制源码进行修改交付,导致【标准版本】和【交付版本】很难实现代码同步,代码维护困难。
  • PC端二次开发的关键在于实现单一源码的复用,以满足不同业务功能的二次开发需求。这种模式不仅支持项目交付时的标准版本,还能够灵活增补定制化功能,为开发注入更多可能性。

# 适用人员

  • 业务开发人员。
  • 二开交付人员。
  • ...

# 二、环境准备

# 技术栈

推荐使用:

  • Vue@3.2.27以上版本。
  • Node.js 18.20.3以上版本。
  • yarn包管理工具,版本1.22.22。

# 环境配置

  • node.js

具体配置请参照文档:本地部署运行-node

  • yarn

具体配置请参照文档:本地部署运行-yarn

  • npm包开发准备

具体配置请参照文档:本地部署运行-6. npm包开发。

# 开发工具

  • 推荐使用的代码编辑器(如 VS Code)。

# 二开实现

  • 二开依赖@imom/vue-2nd-kit依赖包实现。
  • 每个业务功能都是一个npm包的方式。
  • 共享同一份的变量、方法,实现数据的统一。

# 三、二次开发框架概览

# 框架架构

展示框架的整体架构图。 说明各模块的功能和相互关系。

pc端项目二开

# 核心组件

列举框架提供的主要组件。 简述每个组件的作用和使用场景。

# SearchForm-查询表单

核心组件-searchForm

# ButtonGroup-按钮组

核心组件-buttonGroup

# Table-表格

核心组件-table

# Form-表单

核心组件-form

# Tabs-多页签

核心组件-tabs

# LeftTree-左侧树

待完善。

# 四、工具包API概览

提供@imom/vue-2nd-kit中常用方法、属性、插槽和变量的清单。

# 模型

# modelProps

公共props配置,提供二开标准的props配置。

  • 使用
<script setup lang="ts">
import { modelProps } from "@imom/vue-2nd-kit";

const props = defineProps({
  ...modelProps
  // 可继续添加自定义组件属性
})
</script>
1
2
3
4
5
6
7
8
  • 定义
属性名 类型 默认值 说明
customSetup Function ({ state, config }: CustomParamsType) => ({ state, config }) setup时期数据初始化(此时未初始化完成,入参无methods)。
customBeforeMount Function (_: CustomLifecycleParamsType) => _ vue的beforeMount生命周期
customMounted Function async (_: CustomLifecycleParamsType) => void 0 vue的mounted生命周期
customBeforeUnmount Function async (_: CustomLifecycleParamsType) => void 0 vue的beforeUnmount生命周期
customUnmounted Function async (_: CustomLifecycleParamsType) => void 0 vue的unmounted生命周期
beforeSearch Function async (_: CustomLifecycleParamsType) => _ 调用搜索前
tableCellClick Function async (_rowData: RowDataType): HookReturnDataType => void 0 表格单元格点击事件
tableClickAction Function async (_rowData: RowDataType, _type: string): HookReturnDataType => void 0 表格操作列点击事件
beforeFetchList Function async (_params: ObjType): HookReturnDataType => _params 调用查询列表数据前
afterFetchList Function async (_responseBody: ResponseBodyType): HookReturnDataType => _responseBody 调用查询列表后
catchFechListError Function async (_error: any): HookReturnDataType => void 0 调用查询列表数据出现错误时
tabsChange Function (_: TabItemType) => void 0 子表tabs切换时
setButtonGroupAttrs Function ({ config, state: _state }: CustomParamsType): Reactive<ObjType> => config 设置按钮组属性
beforeFormSubmit Function async (_: CustomParamsType) => void 0 表单提交事件前
customApi Function (_type: string): HookReturnDataType \| undefined => void 0 自定义api接口

# modelEmits

公共emits配置,提供二开标准的emits配置。

  • 使用
<script setup lang="ts">
import { modelEmits } from "@imom/vue-2nd-kit";

const emits = defineEmits([
  ...modelEmits
  // 可继续添加页面自定义事件
]);
</script>
1
2
3
4
5
6
7
8
  • 定义
事件名 类型 说明
current-change (currentRow: RowDataType) => void 表格当前选中改变
select-change (selectedData: RowDataType[]) => void 表格选中改变
select-all (selectedData: RowDataType[]) => void 表格全选

# modelState

公共状态配置,提供二开标准的变量状态配置。

  • 使用
<script setup lang="ts">
import { modelProps, modelState, modelConfig } from "@imom/vue-2nd-kit";
import pageConfig from "./pageConfig";

const props = defineProps({
  ...modelProps
});

// customSetup生命周期处理state、config
const defaultSetupValue = props.customSetup({
  state: {
    ...modelState // 若不允许外部在setup时修改state,可不写
    // 可继续添加页面变量
  },
  config: {
    ...modelConfig,
    ...pageConfig
  }
});
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
  • 定义
变量名 类型 默认值 说明
loading boolean false 页面数据加载中状态
searchFormData object {} searchForm表单数据
tableParams object { current: 1, size: 10} 表格参数,current当前页,size每页条数
selectedData array [] 勾选数据
currentRow object | null null 当前选中行
tableData array [] 表格数据
tableDataTotal number 0 表格总条数
formData object {} form表单数据
isFormVisible boolean false form表单是否显示

# modelConfig

公共页面组件配置,提供二开标准的页面配置。

  • 使用
<script setup lang="ts">
import { modelProps, modelState, modelConfig } from "@imom/vue-2nd-kit";
import pageConfig from "./pageConfig";

const props = defineProps({
  ...modelProps
});

// customSetup生命周期处理state、config
const defaultSetupValue = props.customSetup({
  state: {
    ...modelState
  },
  config: {
    ...modelConfig, // 若不允许外部在setup时修改config,可不写
    ...pageConfig
    // 可继续添加页面组件配置
  }
});
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
  • 定义
属性名 默认值 说明
pageInfo { searchTitle: "", title: "" } 页面折叠面板标题
searchForm { formItemList: [], attrs: {} } 搜索表单配置
buttonGroup { buttonList: [], attrs: {} } 按钮组配置
table { columnConfig: [], attrs: {} } 表格配置
form { attrs: {} } 表单配置
tabs { tabItems: [], attrs: {} } 多页签配置
leftTree { attrs: {} } 左侧树配置

# 方法

# createPageContext-创建页面变量

返回包含共享页面数据、配置和方法的上下文对象。

  • 使用
<script setup lang="ts">
import { createPageContext, modelProps, modelState, modelConfig, modelEmits } from "@imom/vue-2nd-kit";
import pageConfig from "./pageConfig";
import { api } from "./api";

const props = defineProps({
  ...modelProps
});
const emits = defineEmits([...modelEmits]);

// customSetup生命周期处理state、config
const defaultSetupValue = props.customSetup({
  state: {
    ...modelState
  },
  config: {
    ...modelConfig,
    ...pageConfig
  }
});

const tableRef = ref(null);
const formRef = ref(null);

// 创建页面二开标准的变量状态$state、组件配置$config、方法$methods、组件实例$ref
const { $state, $config, $methods, $ref } = createPageContext({
  props,
  emits,
  ref: {
    tableRef,
    formRef
  },
  state: {
    ...defaultSetupValue.state // 外部修改后的state变量
  },
  config: {
    ...defaultSetupValue.config // 外部修改后的组件config配置
  },
  api
});
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
  • props
名称 类型说明 说明
props defineProps返回值 业务页面的props结合工具包的modelProps后生成的属性对象
emits defineEmits返回值 业务页面的emits结合工具包的modelEmits后生成的事件对象
ref ref对象集 定义:表格的ref-tableRef、表单的ref-formRef、多页签tabs中的组件集合-compRef
state reactive返回值 业务页面的reactive结合工具包的modelState后生成的响应式对象
api 请求Promise对象集 api请求对象
config reactive返回值 页面组件配置对象

# setFormItemListOp-处理formItemList数据

处理formItemList数据,包括对数据的新增、更新、删除、替换等方法,并返回处理后的数据。

  • 使用
<script setup lang="ts">
import { setFormItemListOp } from "@imom/vue-2nd-kit";
import pageConfig from "./pageConfig";

// 新增
const insertFormItemList = setFormItemListOp.insert(pageConfig.searchForm.formItemList, [
  { label: "测试", prop: "test" },
  { label: "名称", prop: "name" },
]);

// 更新
const updateFormItemList = setFormItemListOp.update(pageConfig.searchForm.formItemList, [
{ label: "新名称", prop: "name"}
]);

// 删除
const deleteFormItemList = setFormItemListOp.delete(pageConfig.searchForm.formItemList, ["test"]);

// 替换
const replaceFormItemList = setFormItemListOp.replace(pageConfig.searchForm.formItemList, {
  name: { label: "编码", "prop": "code"}
});
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
  • 参数说明
属性名 类型 说明
insert (formItemList: FormItemListType, formItems: FormItemListType, idx: number \| undefined) => FormItemListType formItemList:表单项配置,formItems:要插入的表单项数据,idx:插入位置索引
update (formItemList: FormItemListType, datas: FormItemListType) => FormItemListType formItemList:表单项配置,formItems:要更新的表单项数据
delete (formItemList: FormItemListType, datas: string[]) => FormItemListType formItemList:表单项配置,datas:要删除的prop数组
replace (formItemList: FormItemListType, data: Record<string, FormItemType>) => FormItemListType formItemList:表单项配置,data:要替换的表单项对象

# setButtonListOp-处理buttonList数据

处理buttonList数据,包括对数据的新增、更新、删除、替换等方法,并返回处理后的数据。

  • 使用
<script setup lang="ts">
import { setButtonListOp } from "@imom/vue-2nd-kit";
import pageConfig from "./pageConfig";

// 新增
const insertButtonList = setButtonListOp.insert(pageConfig.buttonGroup.buttonList, [
  { key: "add", text:"添加" },
  { key: "remove", text: "移除" }
])

// 更新
const updateButtonList = setButtonListOp.update(pageConfig.buttonGroup.buttonList, [
  { key: "add", text:"添加" }
]);

// 删除
const removeButtonList = setButtonListOp.remove(pageConfig.buttonGroup.buttonList, ["remove"]);

// 替换
const replaceButtonList = setButtonListOp.replace(pageConfig.buttonGroup.buttonList, {
  add: { key: "create", text:"新增" }
});
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
  • 参数说明
属性名 类型 说明
insert (buttonListConfig: ButtonListType, buttonList: ButtonListType, idx: number \| undefined) => ButtonListType buttonListConfig:按钮组配置,buttonList:要插入的按钮组数据,idx:插入位置索引
update (buttonListConfig: ButtonListType, datas: ButtonListType) => ButtonListType buttonListConfig:按钮组配置,datas:要更新的按钮组数据
delete (buttonListConfig: ButtonListType, datas: string[]) => ButtonListType buttonListConfig:按钮组配置,datas:要删除的按钮组key数组
replace (buttonListConfig: ButtonListType, data: Record<string, ButtonType>) => ButtonListType buttonListConfig:按钮组配置,data:要替换的按钮组数据

# setColumnConfigOp-处理columnConfig数据

处理columnConfig数据,包括对数据的新增、更新、删除、替换等方法,并返回处理后的数据。

  • 使用
<script setup lang="ts">
import { setColumnConfigOp } from "@imom/vue-2nd-kit";
import pageConfig from "./pageConfig";

// 新增
const insertColumnConfig = setColumnConfigOp.insert(pageConfig.table.columnConfig, [
  { field: "newField", title: "新增字段" },
  { field: "insertField", title: "插入字段" }
]);

// 更新
const udpateColumnConfig = setColumnConfigOp.update(pageConfig.table.columnConfig, [
  { field: "insertField", title: "添加字段"  }
]);

// 删除
const deleteColumnConfig = setColumnConfigOp.delete(pageConfig.table.columnConfig, ["newField"]);

// 替换
const replaceColumnConfig = setColumnConfigOp.replace(pageConfig.table.columnConfig, {
  insertField: { field: "name", title: "名称" }
});
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
  • 参数说明
属性名 类型 说明
insert (columnConfig: ColumnConfigType, columns: ColumnConfigType, idx: number \| undefined) => ColumnConfigType columnConfig:表格列配置,columns:要插入的表格列数据,idx:要插入的索引
update (columnConfig: ColumnConfigType, datas: ColumnConfigType) => ColumnConfigType columnConfig:表格列配置,datas:要更新的表格列数据
delete (columnConfig: ColumnConfigType, datas: string[]) => ColumnConfigType columnConfig:表格列配置,datas:要删除的field数组
replace (columnConfig: ColumnConfigType, data: Record<string, ColumnType>) => ColumnConfigType columnConfig:表格列配置,data:要替换的表格列数据

# setTabItemsOp-处理tabItems数据

  • 使用
<script setup lang="ts">
import { markRaw } from "vue";
import { setTabItemsOp } from "@imom/vue-2nd-kit";
import pageConfig from "./pageConfig";
import SubTableComponent from "./SubTableComponent.vue";
import DetailTable from "./DetailTable.vue";

// 新增
const insertTabItems = setTabItemsOp.insert(pageConfig.tabs.tabItems, [
  {
    attrs: { label: "Tab1", name: "Tab1" },
    childNode: { attrs: { parentId: 123 }, component: markRaw(SubTableComponent) }
  }
]);

// 更新
const updateTabItems = setTabItemsOp.update(pageConfig.tabs.tabItems, [
  {
    attrs: { name: "Tab1", label: "页签1" },
  }
]);

// 删除
const deleteTabItems = setTabItemsOp.delete(pageConfig.tabs.tabItems, ["Tab1"])

// 替换
const replaceTabItems = setTabItemsOp.replace(pageConfig.tabs.tabItems, {
  Tab1: {
    attrs: { name: "detailTable", label: "明细表" },
    childNode: { attrs: { id: 123 }, component: markRaw(DetailTable) }
  }
})
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
  • 参数说明
属性名 类型 说明
insert (tabsConfig: TabItemsType, tabItems: TabItemsType, idx: number \| undefined) => TabItemsType tabsConfig:tabs配置项,tabItems:要插入的tabs数据,idx:插入的索引
update (tabsConfig: TabItemsType, datas: TabItemsType) => TabItemsType tabsConfig:tabs配置项,datas:要更新的tabs数据
delete (tabsConfig: TabItemsType, datas: string[]) => TabItemsType tabsConfig:tabs配置项,datas:要删除的name数组
replace (tabsConfig: TabItemsType, data: Record<string, TabItemType>) => TabItemsType tabsConfig:tabs配置项,data:要替换的tabs数据

# 五、二次开发流程

# 业务开发人员

业务集成二开

# 二开交付人员

交付人员二开

# 六、常见问题与解决方案

# 兼容性问题

列举可能遇到的兼容性问题及解决方法。

  • @dme/snack-ui组件库组件属性有误
    • 查看组件库更新日志 (opens new window),确认工程所用版本是否支持该属性。
  • 业务功能包发版失败
    • 查阅本地部署运行-6 npm包开发是否配置正确。

# 性能优化

提供性能优化的建议和技巧。

  1. 减少使用无用的钩子
  2. 非必要依赖,仅在工程中安装依赖,减少将依赖打包到业务功能包中

# 错误排查

说明如何排查常见错误并提供解决方案。

# 1. 包入口文件不正确

可能原因:

  • package.json中的main或module字段配置错误。
  • 引入第三方依赖,但打包时未忽略,导致引入的依赖文件被打包进主文件,打包后目录结构错误。

解决方法:

  • 检查打包产物dist目录,检查package.json中的main和module字段配置是否正确。
  • 检查第三方依赖,确认是否需要忽略,并在业务包中的_build/vite.config.ts中的build.rollupOptions.external进行修改。
# 2. 本地开发时使用insert会插入多次表单项、按钮、表格列等

可能原因:

  • 热重载应用时,生命周期重复执行,导致insert方法重复执行。

解决方法:

  • 添加if判断插入节点或项是否已存在,存在则不重复插入。
# 3. 使用setColumnConfigOp.insert向表格插入列,插入位置不正确

可能原因:

  • 表格有固定列,无法插入最左或左右

解决方法:

  • 删除固定列
# 4. 在配置customSetup时,无法使用$methods

可能原因:

  • customSetup在每次组件实例被创建的时候执行,此时$methods还未定义。

解决方法:

  • 避免在customSetup中使用$methods。
# 5. 多处引用同一个业务组件并进行二开时,组件之间配置互相干扰、污染

可能原因:

  • 业务组件引入的pageConfig.js文件直接引用后被修改,且作用域在顶级,从而全局影响。

解决方法:

  • 使用方法返回pageConfig对象,避免直接引用。
// pageConfig.js

export default function () {
  return {
    pageInfo: {
      // ...
    },
    searchForm: {
      // ...
    },
    table: {
      // ...
    },
    form: {
      // ...
    }
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!-- index.vue -->

<script setup>
// ...其他代码
import pageConfig from "./pageConfig";

import { createPageContext, modelProps, modelState, modelConfig } from "@imom/vue-2nd-kit";

const props = defineProps({
  ...modelProps
});
const emits = defineEmits([...modelEmits]);

const defaultSetupValue = props.customSetup({
  state: {
    formDataInit: {},
    ...modelState
  },
  config: {
    ...modelConfig,
    ...pageConfig() // 调用方法获取配置
  }
});

// ...其他代码
</script>

<!-- ... -->
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
在线编辑 (opens new window)
最近更新
01
交付人员二开
09-16
02
业务集成二开
09-16
03
事务集成
07-09
更多文章>
Theme by Vdoing | Copyright © 2023-2026 SIE
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式