Vue3+Vite4实战:手把手教你用Easy Process仿钉钉搭建OA审批流(附完整源码)
2026/6/13 7:02:48 网站建设 项目流程

Vue3+Vite4实战:用Easy Process构建企业级OA审批系统

最近在重构公司内部管理系统时,遇到了一个典型需求:需要一个类似钉钉的审批流程功能。调研了市面上各种方案后,最终选择了基于Vue3和Vite4的Easy Process开源项目。这个决策不仅节省了至少两周的开发时间,还带来了意想不到的灵活性和扩展性。本文将分享从零开始集成Easy Process的全过程,包括几个关键的技术突破点和实际踩坑经验。

1. 环境搭建与项目初始化

在开始之前,确保你的开发环境满足以下要求:

  • Node.js ≥ 14.x
  • npm ≥ 6.x 或 yarn ≥ 1.22.x
  • Vue3 基础开发环境

推荐使用VSCode作为开发工具,并安装以下插件提升开发效率:

  • Volar (Vue3官方推荐插件)
  • ESLint
  • Prettier - Code formatter

创建新项目并集成Easy Process:

# 创建Vue3项目 npm create vite@latest oa-workflow --template vue # 进入项目目录 cd oa-workflow # 安装Easy Process npm install easy-process

项目结构初始化后,需要在src/main.js中做基础配置:

import { createApp } from 'vue' import App from './App.vue' import EasyProcess from 'easy-process' import 'easy-process/dist/style.css' const app = createApp(App) app.use(EasyProcess) app.mount('#app')

注意:如果遇到样式冲突问题,可以在vite.config.js中添加CSS预处理配置,确保Easy Process的样式优先级正确。

2. 核心组件集成与配置

Easy Process的核心是流程设计器组件,它提供了类似钉钉的拖拽式流程配置界面。在项目中使用时,需要先准备基础数据模型:

// src/store/process.js export const defaultProcess = { processId: 'leave-request', processName: '请假审批流程', nodeConfig: { nodeName: '发起人', nodeType: 'start', config: { approvers: [], formItems: [] }, childNode: null } }

在页面组件中引入设计器:

<template> <div class="process-container"> <process-designer :data="processData" @save="handleSave" @validate="handleValidate" /> </div> </template> <script setup> import { ref } from 'vue' import { defaultProcess } from '@/store/process' const processData = ref(JSON.parse(JSON.stringify(defaultProcess))) const handleSave = (result) => { console.log('流程数据:', result) // 这里可以对接后端API保存流程 } const handleValidate = ({ valid, messages }) => { if (!valid) { alert(`流程校验失败: ${messages.join('\n')}`) } } </script>

关键配置参数说明

参数名类型必填说明
dataObject流程初始数据
readonlyBoolean是否只读模式
hideToolbarBoolean是否隐藏工具栏
customNodesArray自定义节点类型

3. 自定义节点开发实战

Easy Process的强大之处在于支持完全自定义的节点类型。假设我们需要添加一个"财务审核"节点,下面是具体实现步骤:

3.1 创建节点组件文件

src/components/process/nodes目录下新建finance文件夹,包含两个文件:

  • FinanceNode.vue (节点展示组件)
  • FinanceDrawer.vue (节点配置组件)

3.2 实现节点逻辑

<!-- FinanceNode.vue --> <template> <div class="finance-node"> <div class="node-header" :style="{ backgroundColor: nodeStyle.bgColor }"> <span>{{ node.nodeName }}</span> </div> <div class="node-body"> <p v-if="config.amountLimit">金额限制: {{ config.amountLimit }}元</p> </div> </div> </template> <script setup> import { computed, inject } from 'vue' import { KEY_VALIDATOR } from '../../config/keys' const props = defineProps({ node: Object, tempNodeId: String }) const config = computed(() => props.node.config || {}) const nodeStyle = computed(() => ({ bgColor: '#FFA500', color: '#FFFFFF' })) // 注册验证逻辑 const validator = inject(KEY_VALIDATOR) validator.register(props.tempNodeId, () => { if (!config.value.amountLimit) { return { valid: false, message: '必须设置金额限制' } } return { valid: true } }) </script>

3.3 注册节点类型

在项目入口文件中添加节点类型注册:

// src/process-config.js export const customNodes = [{ type: 'finance', title: '财务审核', icon: 'finance', defaultConfig: { amountLimit: 5000, requireInvoice: true } }]

3.4 在流程设计器中启用自定义节点

<process-designer :data="processData" :custom-nodes="customNodes" />

4. 高级功能与性能优化

当流程变得复杂时,需要考虑性能和用户体验的优化。以下是几个实战验证有效的技巧:

4.1 异步加载配置

对于大型流程,可以使用动态导入减少初始加载时间:

const loadProcessConfig = async () => { const { default: config } = await import('@/api/processConfig') processData.value = config }

4.2 使用Web Worker处理复杂计算

创建src/workers/process.worker.js:

self.onmessage = function(e) { const { type, data } = e.data if (type === 'validate') { // 执行复杂验证逻辑 const result = complexValidation(data) postMessage(result) } } function complexValidation(process) { // 实现深度校验逻辑 return { valid: true, warnings: [] } }

在组件中使用:

import ProcessWorker from '@/workers/process.worker?worker' const worker = new ProcessWorker() worker.onmessage = (e) => { console.log('校验结果:', e.data) } const validateComplexProcess = () => { worker.postMessage({ type: 'validate', data: processData.value }) }

4.3 流程版本控制

实现简单的本地历史记录功能:

const processHistory = ref([]) const currentVersion = ref(0) const saveVersion = () => { processHistory.value = processHistory.value.slice(0, currentVersion.value + 1) processHistory.value.push(JSON.parse(JSON.stringify(processData.value))) currentVersion.value = processHistory.value.length - 1 } const undo = () => { if (currentVersion.value > 0) { currentVersion.value-- processData.value = JSON.parse(JSON.stringify( processHistory.value[currentVersion.value] )) } } const redo = () => { if (currentVersion.value < processHistory.value.length - 1) { currentVersion.value++ processData.value = JSON.parse(JSON.stringify( processHistory.value[currentVersion.value] )) } }

5. 企业级集成方案

在实际企业环境中,审批流程通常需要与现有系统深度集成。以下是几个关键集成点:

5.1 与后端API对接

创建API服务层:

// src/api/process.js import axios from 'axios' export const saveProcess = async (data) => { try { const res = await axios.post('/api/process/save', data) return res.data } catch (error) { console.error('保存流程失败:', error) throw error } } export const loadProcess = async (processId) => { const res = await axios.get(`/api/process/${processId}`) return res.data }

5.2 权限控制集成

在流程设计器中添加权限检查:

<template> <process-designer :readonly="!hasEditPermission" /> </template> <script setup> import { computed } from 'vue' import { useStore } from 'vuex' const store = useStore() const hasEditPermission = computed(() => store.getters.hasPermission('process:edit') ) </script>

5.3 与表单系统集成

创建表单配置组件:

<template> <div class="form-config"> <h3>表单字段配置</h3> <draggable v-model="formItems" item-key="id" > <template #item="{ element }"> <form-item-config :item="element" /> </template> </draggable> <button @click="addFormItem">添加字段</button> </div> </template> <script setup> import { computed } from 'vue' import draggable from 'vuedraggable' const props = defineProps(['node']) const emit = defineEmits(['update:node']) const formItems = computed({ get: () => props.node.config.formItems || [], set: (value) => { emit('update:node', { ...props.node, config: { ...props.node.config, formItems: value } }) } }) const addFormItem = () => { formItems.value.push({ id: Date.now(), type: 'text', label: '新字段', required: false }) } </script>

6. 部署与持续集成

将流程设计器集成到生产环境时,需要考虑以下最佳实践:

6.1 构建优化配置

在vite.config.js中添加特定配置:

import { defineConfig } from 'vite' export default defineConfig({ build: { rollupOptions: { output: { manualChunks: { 'easy-process': ['easy-process'] } } } } })

6.2 Docker部署方案

创建Dockerfile:

# 使用官方Node镜像 FROM node:16-alpine as builder # 设置工作目录 WORKDIR /app # 复制依赖定义 COPY package*.json ./ # 安装依赖 RUN npm install # 复制源代码 COPY . . # 构建应用 RUN npm run build # 使用Nginx作为生产服务器 FROM nginx:stable-alpine # 复制构建产物 COPY --from=builder /app/dist /usr/share/nginx/html # 复制Nginx配置 COPY nginx.conf /etc/nginx/conf.d/default.conf # 暴露端口 EXPOSE 80 # 启动Nginx CMD ["nginx", "-g", "daemon off;"]

配套的nginx.conf配置:

server { listen 80; server_name localhost; location / { root /usr/share/nginx/html; index index.html; try_files $uri $uri/ /index.html; } location /api { proxy_pass http://backend:3000; proxy_set_header Host $host; } }

6.3 CI/CD流水线配置

创建.github/workflows/deploy.yml:

name: Deploy Workflow on: push: branches: [ main ] jobs: build-and-deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Set up Node.js uses: actions/setup-node@v2 with: node-version: '16' - name: Install dependencies run: npm ci - name: Build run: npm run build - name: Deploy to Server uses: appleboy/scp-action@master with: host: ${{ secrets.SERVER_HOST }} username: ${{ secrets.SERVER_USER }} key: ${{ secrets.SSH_KEY }} source: "dist/" target: "/var/www/oa-workflow"

在实际项目部署中,我们遇到了一个典型问题:当流程节点超过50个时,设计器会出现明显的性能下降。通过分析发现,主要瓶颈在于Vue的响应式系统对大型对象的处理。解决方案是使用shallowRef替代ref处理流程数据,并实现节点的虚拟滚动渲染,这使得即使处理100+节点的复杂流程也能保持流畅交互。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询