vue 实现审批流程
实现审批流程的基本思路
审批流程通常涉及多个步骤,如提交申请、部门审批、上级审批等。Vue.js 适合构建此类动态流程,结合状态管理和组件化设计可以实现灵活的审批系统。
使用 Vuex 管理审批状态
审批流程的状态管理是关键。Vuex 提供集中式存储,适合管理多步骤审批的状态。
// store/modules/approval.js
const state = {
currentStep: 1,
steps: [
{ id: 1, name: '提交申请', status: 'pending' },
{ id: 2, name: '部门审批', status: 'waiting' },
{ id: 3, name: '上级审批', status: 'waiting' }
]
}
const mutations = {
APPROVE_STEP(state, stepId) {
state.steps.find(step => step.id === stepId).status = 'approved'
state.currentStep += 1
},
REJECT_STEP(state, stepId) {
state.steps.find(step => step.id === stepId).status = 'rejected'
}
}
动态渲染审批步骤组件
根据当前步骤动态渲染不同审批组件,保持界面与状态同步。
<template>
<div class="approval-flow">
<div v-for="step in steps" :key="step.id"
:class="['step', step.status]">
{{ step.name }}
</div>
<component :is="currentComponent" @approve="handleApprove" @reject="handleReject"/>
</div>
</template>
<script>
export default {
computed: {
steps() {
return this.$store.state.approval.steps
},
currentComponent() {
const step = this.$store.state.approval.currentStep
return () => import(`@/components/Step${step}`)
}
},
methods: {
handleApprove() {
this.$store.commit('APPROVE_STEP', this.$store.state.approval.currentStep)
},
handleReject() {
this.$store.commit('REJECT_STEP', this.$store.state.approval.currentStep)
}
}
}
</script>
审批流程可视化
使用进度条或流程图增强用户体验,清晰展示审批进度。
<template>
<div class="progress-container">
<div v-for="(step, index) in steps" :key="step.id" class="step-node">
<div class="connector" v-if="index > 0" :class="{ active: step.status !== 'waiting' }"></div>
<div class="node" :class="step.status"></div>
<div class="step-label">{{ step.name }}</div>
</div>
</div>
</template>
<style scoped>
.progress-container {
display: flex;
justify-content: space-between;
}
.node {
width: 20px;
height: 20px;
border-radius: 50%;
background: #ccc;
}
.node.approved {
background: #4CAF50;
}
.node.rejected {
background: #F44336;
}
.connector {
flex-grow: 1;
height: 2px;
background: #ccc;
margin-top: 9px;
}
.connector.active {
background: #4CAF50;
}
</style>
与后端API集成
审批流程通常需要持久化数据,通过axios与后端API交互。
// api/approval.js
import axios from 'axios'
export default {
submitApplication(data) {
return axios.post('/api/approval/submit', data)
},
approveStep(stepId) {
return axios.post(`/api/approval/${stepId}/approve`)
},
getApprovalStatus(approvalId) {
return axios.get(`/api/approval/${approvalId}/status`)
}
}
权限控制实现
不同审批步骤可能需要不同权限,使用路由守卫控制访问。
// router.js
router.beforeEach((to, from, next) => {
const requiresApprover = to.matched.some(record => record.meta.requiresApprover)
const userRole = store.state.user.role
if (requiresApprover && userRole !== 'approver') {
next('/forbidden')
} else {
next()
}
})
审批历史记录
记录审批操作历史,方便追踪和审计。
<template>
<div class="approval-history">
<div v-for="(log, index) in history" :key="index" class="log-entry">
<span class="timestamp">{{ log.timestamp }}</span>
<span class="action">{{ log.action }}</span>
<span class="actor">{{ log.actor }}</span>
</div>
</div>
</template>
<script>
export default {
data() {
return {
history: []
}
},
created() {
this.fetchHistory()
},
methods: {
async fetchHistory() {
const response = await this.$api.approval.getHistory(this.approvalId)
this.history = response.data
}
}
}
</script>
响应式设计考虑
确保审批流程在不同设备上都能良好显示。
/* 响应式布局 */
@media (max-width: 768px) {
.progress-container {
flex-direction: column;
align-items: flex-start;
}
.step-node {
display: flex;
align-items: center;
margin-bottom: 10px;
}
.connector {
width: 2px;
height: 20px;
margin: 0 9px;
}
}






