前端集成

willian fu 2022 ~

前端集成

前端vue项目目录结构都是大致相同的,那么可以进行如下方式合并代码

代码合并

1、合并main.js

将wflow项目和目标项目的main.js中代码进行合并,主要是合并import导入的依赖还有注册全局组件,注意不要遗漏

2、转移静态资源

将wflow的 publicassets 目录下的静态资源文件转移到目标项目

3、合并接口api

wflowapi目录下所有接口的api文件复制到目标项目的 api 目录下面,然后把wflow的api目录下 request.js 里面的syncRequest() 函数,拷贝到目标项目的 request.js

4、复制公共组件

复制 wflow components 目录下的common目录连同里面的公共组件一起复制到目标项目 components 目录下

5、复制wflow页面组件

在目标项目的views 目录下新建目录名称为 wflow,将wflow项目的 views目录内所有文件及目录都复制到该新建的wflow目录内,然后使用开发工具执行全局替换组件内import 的路径,示例如下:

wflow内组件引用方式 import FormsPanel from @/views/admin/FormsPanel.vue

新引入方式为 import FormsPanel from @/views/wflow/admin/FormsPanel.vue

如上方式将views/wflow/内所有组件的相互引用路径批量修改,注意相对路径也要修改,根据build的时候报错信息来修改指定组件即可

6、合并npm依赖

合并packge.json中所有npm依赖到目标项目,注意包括dependenciesdevDependencies的依赖

7、合并Vue项目配置config

根据 vue2/3 去配置如下配置项

Vue2(vue.config.js)

const MonacoEditorPlugin = require('monaco-editor-webpack-plugin')

module.exports = {
  //其他配置项......
  configureWebpack: {
    plugins: [
      new MonacoEditorPlugin({ languages: ['javascript', 'html', 'css', 'json'] })
    ]
  }
}

Vue3(vite.config.js)

import vueJsx from '@vitejs/plugin-vue-jsx'

export default defineConfig({
  //其他配置项......
  plugins: [
    vue(),
    vueJsx()
  ],
  resolve: {
    alias: {  // 配置路径别名
      '@': resolve('src')
    },
  },
  css: {
    preprocessorOptions: {   // css预处理器
      less: {
        // 引入全局的Less库
        additionalData: '@import "./src/assets/theme.less";'
      },
    },
  },
  optimizeDeps: {
    include: [
      `monaco-editor/esm/vs/language/json/json.worker`,
      `monaco-editor/esm/vs/language/css/css.worker`,
      `monaco-editor/esm/vs/language/html/html.worker`,
      `monaco-editor/esm/vs/language/typescript/ts.worker`,
      `monaco-editor/esm/vs/editor/editor.worker`
    ],
  },
  esbuild: {
    jsxFactory: 'h',
    jsxFragment: 'Fragment',
    jsxInject: "import { h } from 'vue';"
  }
}

8、合并Vuex/pina的state

Vuex

state: {
    nodeMap: new Map(),
    isEdit: null,
    loginUser: JSON.parse(localStorage.getItem('loginUser') || '{}'),
    selectedNode: {},
    selectFormItem: null,
    design:{},
  },
  mutations: {
    selectedNode(state, val) {
      state.selectedNode = val
    },
    loadForm(state, val){
      state.design = val
    },
    setIsEdit(state, val){
      state.isEdit = val
    }
  },

Pina

新建 modules wflow.js,参考配置如下

const useWflowStore = defineStore(
  'wflow', {
    state: () => ({
      nodeMap: new Map(),
      isEdit: null,
      loginUser: JSON.parse(localStorage.getItem('loginUser') || '{}'),
      selectedNode: {},
      selectFormItem: null,
      design: {},
    }),
  }
)
export default useWflowStore

为了兼容之前 Vuex的写法 this.$store.state.xxxx,在 main.jsuseWflowStore 注册到全局

import useWflowStore from '@/store/modules/wflow'

const app = createApp(App)
window.$vueApp = app
window.$vCtx = app.config.globalProperties
import('./utils/Injection')

//注册到全局后可以使用 this.$wflow.xxx访问变量了
window.$vCtx.$wflow = useWflowStore() 

然后全局替换 this.$store.state.this.$wflow. 即可

9、配置loginUser

上一步中我们看到了 state 中有个对象 loginUser,很多地方有用到它,我们要对它进行正确配置

在系统登录成功后,获取到了用户信息之后,我们要去给这个 loginUser 赋值,结构如下

{
    id: '用户id',
    name: '用户显示的名称',
    avatar: '头像图片,可为空',
    type: 'user' //固定值
}

注意

请保证登录后这个地方一致有值且和当前登录的用户信息保持一致,且 id 字段值的类型要与后台返回的类型一致,例如有的系统 userId是数值类型,有的是字符串 ,这样wflow代码内 loginUser.id === user.id 为false,这里要注意修改id类型或者把 === 改为 ==

10、路由配置

如果是使用动态路由的话,路由就不用配置在代码中了,直接配置到后台管理系统的菜单管理中,以下是需要配置路由的页面

  • 审批列表:@/views/wflow/workspace/oa/FromsApp
  • 待我处理:@/views/wflow/workspace/oa/UnFinished
  • 已处理的:@/views/wflow/workspace/oa/Finished
  • 我发起的:@/views/wflow/workspace/oa/MySubmit
  • 关于我的:@/views/wflow/workspace/oa/CcMe
  • 数据管理:@/views/wflow/admin/ProcessInstanceManage
  • 流程管理:@/views/wflow/admin/FormsPanel
  • 流程设计:@/views/wflow/admin/FormProcessDesign

🎈 注意:流程设计这个路由不要显示到菜单里面!!!

11、样式冲突

引入wflow后可能由于目标项目存在一些全局样式类名与wflow内的类名重复,导致 wflow 系统组件样式被污染变化,这种情况需要手动F12 打开开发者工具进行定位,手动修改复原wflow的样式

修改技巧

先在浏览器内的开发者工具中进行样式修改,然后复原样式后根据修改的 class 类名全局搜索对应 .vue 组件 <style>中的类名,修改对应样式

集成问题收集

Vue容器组件不显示效果

需要在vue.config.js 中加配置 runtimeCompiler: true,开启动态编译

module.exports = {
    //其他配置项
	runtimeCompiler: true,
}