封装一个审核进度的进度条组件,可左右无限延伸

废话不多说,直接上图

上代码

先封装进度条组件

examin_step.vue

<template>
	<div class="d-examineBox cf" v-if="(processList && processList.length > 0) || (review && review.length > 0)">
		<h3>审核进度</h3>
		<div class="d-steps cf">
			<span v-for="(item,index) in processList" :key="index" :status="item.status">
                <em>{{ item.username }}</em>
                <i>{{ item.user_type_name || '' }}</i>

                <template v-if="item.is_reject == 100">
                    <em text>已驳回&nbsp;<el-tooltip v-if="item.reject_msg" placement="top" :content="item.reject_msg"><b>{{item.reject_msg }}</b></el-tooltip></em>
                    <!--时间-->
                    <em>{{item.reject_date ? $tool.getFormatByCode(item.reject_date , 3) : '-'}}</em>
                </template>
                <template v-else>
                    <em v-if="item.status === 0">发起&nbsp;<el-tooltip v-if="item.service_type_name" placement="top" :content="item.service_type_name"><b>{{item.service_type_name }}</b></el-tooltip></em>
                    <em v-if="item.status === 100" text>审核中</em>
                    <em v-if="item.status === 300" text>已通过&nbsp;<el-tooltip v-if="item.examine_msg" placement="top" :content="item.examine_msg"><b>{{item.examine_msg }}</b></el-tooltip></em>
                    <em v-if="item.status === 400" text>已拒绝&nbsp;<el-tooltip v-if="item.examine_msg" placement="top" :content="item.examine_msg"><b>{{item.examine_msg }}</b></el-tooltip></em>
                    <em v-if="item.status === 500" text>已撤回&nbsp;{{item.service_type_name}}</em>
                    <!--时间-->
                    <em>{{(item.op_date && (item.status === 0 || item.status === 100 || item.status === 300 || item.status === 400 || item.status === 500)) ? $tool.getFormatByCode(item.op_date , 3) : '-'}}</em>
                </template>

                
                <!-- 加签 -->
                <a href="javascript:;" v-if="addStep && (item.status == 100 || item.status == 200) && !item.isAdd" class="a-addStep" @click="addStepBy(item)" title="添加审核人员">+</a>
                <!-- 删除加签 -->
                <a href="javascript:;" v-if="item.isAdd" class="a-deleteStep" @click="deleteStepBy(index)" :title="'删除'+item.username">---</a>
			</span>
		</div>
        <div class="d-review cf" v-if="review && review.length > 0">
            <strong>抄送人员</strong>
            <span>
                <em v-for="(item,index) in review" :key="index">{{ item.user_type_name + '-' + item.username }}</em>
            </span>
        </div>

        <!-- 选择人 -->
		<dialogChooseUser ref="dialogChooseUser" @callBack="dialogChooseUser_callBack" />
	</div>
</template>

<script>
import dialogChooseUser from './dialogChooseUser'
export default {
    props: {
        //进度
		process: {
			type: Array,
			default: []
        },
        //抄送人
		review: {
			type: Array,
			default: []
		},
        //是否有加签
        addStep : {
            type : Boolean,
            default : false
        },
	},
    components : {
        dialogChooseUser
    },
	data() {
		return {
            processList : [],
		}
	},
	watch: {
		process: {
			handler(val) {
                //检查是否有加签
                this.checkIsAdd()
				console.log('进度',val)
			},
			deep: true
        },
        review: {
			handler(val) {
				console.log('抄送人',val)
			},
			deep: true
        },
      
       
	},
	methods: {
        //删除加签的审核人
        deleteStepBy(index){
            this.processList.splice(index , 1)
        },
        //添加审核人
        addStepBy(itemNow){
            this.previousId = itemNow.id
            this.$refs['dialogChooseUser'].selectedUser = this.processList.filter(c=>c.isAdd && c.isAdd == this.previousId)
            this.$refs['dialogChooseUser'].isOpenExaminCommonUsers = true
            this.$refs['dialogChooseUser'].multiple = true
            this.$refs['dialogChooseUser'].dialogVisible = true
        },
        dialogChooseUser_callBack(data){
            var arr = []
            //在审核人后面+
            var processList = this.processList.filter(c=>!c.isAdd || c.isAdd != this.previousId)
            processList.map((item,index)=>{
                arr.push(item)
                //在操作的这个审核人后面,且它是审核人或者待审核人
                if(item.id == this.previousId && (item.status == 100 || item.status == 200)){
                    data.map((child,childIndex)=>{
                        //用下审核人的字段
                        let user = JSON.parse(JSON.stringify(item))
                        user = Object.assign(user , child)
                        //是新增的,标识
                        user.isAdd = this.previousId
                        user.status = 200
                        user.status_name = '等待上一个审批'
                        user.op_date = ''
                        arr.push(user)
                    })
                }
            })
            this.processList = arr
		},
        //检查是否有加签
        checkIsAdd(){
            this.processList = JSON.parse(JSON.stringify(this.process))
        }
	},
	created() {

	},
	mounted() {
        this.checkIsAdd()
	},
}
</script>

<style scoped lang="less">
.d-examineBox {
	background: #fff;
	position: relative;
	border-radius: 2px;
	margin-bottom: 10px;
	font-style: normal;
	h3 {
		height: 40px;
		line-height: 40px;
		color: #06121e;
		font-size: 14px;
		border-bottom: solid #dbdfe5 1px;
		margin: 0 20px;
	}
	.d-steps {
		position: relative;
		display: flex;
		margin: 0 20px;
        overflow: hidden;
        overflow-x: auto;
        &::-webkit-scrollbar {
            height: 8px;
            width: 3px;
            cursor: pointer;
            border-radius: 4px;
        }
		span {
            flex-shrink: 0;
            display: block;
            position: relative;
            padding: 15px 20px 10px 0;
            margin-top: 20px;
            min-width: 120px;
            &:before {
                content: "";
                width: 8px;
                height: 8px;
                border-radius: 100%;
                overflow: hidden;
                background: #fff;
                position: absolute;
                top: 0;
                left: 10px;
                border: solid rgba(181, 181, 181, 1) 1px;
                z-index: 2;
            }
            &:after {
                content: "";
                display: block;
                height: 1px;
                background: #ececec;
                position: absolute;
                top: 5px;
                left: 0;
                right: 0;
                z-index: 1;
            }
            &:nth-of-type(1):after {
                left: 14px;
            }
            &:nth-last-child(1):after {
                right: unset;
                width: 20px;
            }
            em {
                display: block;
                color: #999;
                line-height: 20px;
                white-space: nowrap;
                font-size:12px;
                text-overflow: ellipsis;
                overflow: hidden;
                max-width: 120px;
				font-style: normal;
                b {
                    
                    cursor: pointer;
                    overflow: hidden;
                    text-overflow: ellipsis;
                    white-space: nowrap;
                }
                &:nth-of-type(1){
                    color:#333;font-size:14px; line-height: 25px;
                    &:before {
                        content: "";
                        width: 6px;
                        height: 6px;
                        border-radius: 100%;
                        overflow: hidden;
                        background: rgba(181, 181, 181, 1);
                        position: absolute;
                        top: 2px;
                        left: 12px;
                        z-index: 2;
                    }
                }
            }
            i{
				font-style: normal;
                display: inline-block; background: #E7F4FF; font-size:10px; color:#1890FF; border:solid #D9ECFF 1px; border-radius: 2px; height:18px; line-height: 18px; padding:0 5px;
            }
            .a-addStep{
                position: absolute; top:-2px; left:80px; z-index:2; background:rgba(24,144,255,0.5); transition: all 0.3s ease; color:#fff; width:16px; height:16px; font-size:16px; border-radius: 100%; line-height: 14px; text-align: center;
                &:before{
                    content: "";
                    display: block;
                    height: 1px;
                    background: #ececec;
                    position: absolute;
                    top: 7px;
                    left: -60px;
                    right: 16px;
                    z-index: 1;
                }
                &:hover{
                    background:rgba(24,144,255,1); 
                }
            }
            .a-deleteStep{
                position: absolute; top:12px; left:50px; background: rgba(255,0,0,0.3); color:#fff; width:16px; height:16px; font-size:9px; border-radius: 100%; line-height: 14px; text-align: center; transition: all 0.3s ease;
                &:hover{
                    background: rgba(255,0,0,1); 
                }
            }
            // 审核中
            &[status="100"] {
                &:before {
                border-color: #ff6612;
                }
                em:nth-of-type(1):before {
                background: #ff6612;
                }
                em[text] {
                color: #ff6612;
                }
            }

            // 拒绝
            &[status="400"] {
                &:before {
                border-color: #ff0000;
                }
                em:nth-of-type(1):before {
                background: #ff0000;
                }
                em[text] {
                color: #ff0000;
                }
            }

            // 同意
            &[status="300"] {
                &:before {
                border-color: #33be6f;
                }
                em:nth-of-type(1):before {
                background: #33be6f;
                }
                em[text] {
                color: #33be6f;
                }
            }
            // 撤回
            &[status="500"] {
                &:before {
                border-color: #909399;
                }
                em:nth-of-type(1):before {
                background: #909399;
                }
                em[text] {
                color: #909399;
                }
            }
		}
        
	}
    .d-review {
        position: relative; margin: 0 20px; border-top:solid #dbdfe5 1px; padding:10px 0; display: flex; align-items: center;
        strong{ display: block; flex-shrink: 0; white-space: nowrap; font-weight: 400; }
        span{
            flex:1; display: flex; flex-wrap: wrap; padding-left:5px;
            em{
                display: block; height:30px; line-height: 30px; padding:0 20px; border:solid #E6E8EB 1px; margin:5px; border-radius: 2px;
            }
        }
    }
}
</style>

将组件引入到我们自己的项目

import examin_step from '@/components/examin_step.vue'

<examin_step :process="examin_process" :review="examin_review" />	

设置一些模拟数据

  //审核进度
	  examin_process: [
  {
    "id": 26256,
    "workflows_id": 112,
    "workflows_type_name": "行政",
    "workflows_type": 100,
    "username": "张三",
    "store_4s_name_abbreviation": "德众汽车",
    "user_id": 21857,
    "op_date": "2024-05-28 17:12:57",
    "user_type_name": "测试工程师",
    "examine_msg": "",
    "service_type": "350100",
    "status": 0,
    "sort": 0,
    "is_lose": 100,
    "is_zuofei": 200,
    "zuofei_date": null,
    "is_reject": 200,
    "reject_date": null,
    "reject_msg": null,
    "is_fan_auth": 200,
    "fan_auth_date": null,
    "is_entry": 100,
    "entry_id": 2213,
    "status_name": "撤回审核",
    "current_status": 100,
    "current_status_name": "待审核",
    "is_end": 100,
    "is_first": 100,
    "extend_field": [],
    "service_id": 8,
    "store_4s_id": 2,
    "service_type_name": "行政物耗采购申请",
    "workflows_create_user_id": 10764,
    "reject_process_id": null,
    "workflows_process_exp_id": 5516,
    "service_group": "350100",
    "reject_logs": []
  },
  {
    "id": 26256,
    "store_4s_name_abbreviation": "怀化远众",
    "workflows_id": 112,
    "workflows_type_name": "行政",
    "workflows_type": 100,
    "username": "张三1",
    "user_id": 21857,
    "op_date": "2024-05-28 17:13:28",
    "user_type_name": "测试工程师",
    "status": 500,
    "service_type": "350100",
    "examine_msg": "",
    "is_lose": 100,
    "sort": 1,
    "is_zuofei": 200,
    "zuofei_date": null,
    "is_reject": 200,
    "reject_date": null,
    "reject_msg": null,
    "is_fan_auth": 200,
    "fan_auth_date": null,
    "is_entry": 100,
    "entry_id": 2213,
    "status_name": "已撤回",
    "current_status": 100,
    "current_status_name": "待审核",
    "is_end": 100,
    "is_first": 100,
    "extend_field": [],
    "service_id": 8,
    "store_4s_id": 2,
    "service_type_name": "行政物耗采购申请",
    "workflows_create_user_id": 10764,
    "reject_process_id": null,
    "workflows_process_exp_id": 5516,
    "service_group": "350100",
    "reject_logs": []
  },
  {
    "id": 26259,
    "workflows_id": 112,
    "workflows_type_name": "行政",
    "workflows_type": 100,
    "username": "张三2",
    "store_4s_name_abbreviation": "德众汽车",
    "user_id": 21857,
    "op_date": "2024-05-28 17:13:40",
    "user_type_name": "测试工程师",
    "examine_msg": "",
    "service_type": "350100",
    "status": 0,
    "sort": 0,
    "is_lose": 200,
    "is_zuofei": 200,
    "zuofei_date": null,
    "is_reject": 200,
    "reject_date": null,
    "reject_msg": null,
    "is_fan_auth": 200,
    "fan_auth_date": null,
    "is_entry": 100,
    "entry_id": 2213,
    "status_name": "发起审核",
    "current_status": 100,
    "current_status_name": "待审核",
    "is_end": 100,
    "is_first": 100,
    "extend_field": [],
    "service_id": 8,
    "store_4s_id": 2,
    "service_type_name": "行政物耗采购申请",
    "workflows_create_user_id": 10764,
    "reject_process_id": null,
    "workflows_process_exp_id": 5517,
    "service_group": "350100",
    "reject_logs": []
  },
  {
    "id": 26259,
    "workflows_id": 112,
    "workflows_type_name": "行政",
    "workflows_type": 100,
    "store_4s_name_abbreviation": "怀化远众",
    "username": "张三3",
    "user_id": 21695,
    "op_date": null,
    "user_type_name": "销售主管",
    "status": 100,
    "service_type": "350100",
    "examine_msg": null,
    "is_lose": 200,
    "sort": 1,
    "is_zuofei": 200,
    "zuofei_date": null,
    "is_reject": 200,
    "reject_date": null,
    "reject_msg": null,
    "is_fan_auth": 200,
    "fan_auth_date": null,
    "is_entry": 100,
    "entry_id": 2087,
    "status_name": "待审核",
    "current_status": 100,
    "current_status_name": "待审核",
    "is_end": 100,
    "is_first": 100,
    "extend_field": [],
    "service_id": 8,
    "store_4s_id": 2,
    "service_type_name": "行政物耗采购申请",
    "workflows_create_user_id": 10764,
    "reject_process_id": null,
    "workflows_process_exp_id": 5517,
    "service_group": "350100",
    "reject_logs": []
  },
  {
    "id": 26260,
    "workflows_id": 112,
    "workflows_type_name": "行政",
    "workflows_type": 100,
    "store_4s_name_abbreviation": "怀化远众",
    "username": "张三4",
    "user_id": 21857,
    "op_date": null,
    "user_type_name": "测试工程师",
    "status": 200,
    "service_type": "350100",
    "examine_msg": null,
    "is_lose": 200,
    "sort": 2,
    "is_zuofei": 200,
    "zuofei_date": null,
    "is_reject": 200,
    "reject_date": null,
    "reject_msg": null,
    "is_fan_auth": 200,
    "fan_auth_date": null,
    "is_entry": 100,
    "entry_id": 2213,
    "status_name": "等待上一个审批",
    "current_status": 100,
    "current_status_name": "待审核",
    "is_end": 200,
    "is_first": 200,
    "extend_field": [],
    "service_id": 8,
    "store_4s_id": 2,
    "service_type_name": "行政物耗采购申请",
    "workflows_create_user_id": 10764,
    "reject_process_id": null,
    "workflows_process_exp_id": 5517,
    "service_group": "350100",
    "reject_logs": []
  },
  {
    "id": 26261,
    "workflows_id": 112,
    "workflows_type_name": "行政",
    "workflows_type": 100,
    "store_4s_name_abbreviation": "怀化远众",
    "username": "张三5",
    "user_id": 22172,
    "op_date": null,
    "user_type_name": "后端工程师",
    "status": 200,
    "service_type": "350100",
    "examine_msg": null,
    "is_lose": 200,
    "sort": 3,
    "is_zuofei": 200,
    "zuofei_date": null,
    "is_reject": 200,
    "reject_date": null,
    "reject_msg": null,
    "is_fan_auth": 200,
    "fan_auth_date": null,
    "is_entry": 100,
    "entry_id": 2191,
    "status_name": "等待上一个审批",
    "current_status": 100,
    "current_status_name": "待审核",
    "is_end": 200,
    "is_first": 200,
    "extend_field": [],
    "service_id": 8,
    "store_4s_id": 2,
    "service_type_name": "行政物耗采购申请",
    "workflows_create_user_id": 10764,
    "reject_process_id": null,
    "workflows_process_exp_id": 5517,
    "service_group": "350100",
    "reject_logs": []
  }
],

以上,完事

遥祝大家一切顺利,发大财

相关推荐
IT女孩儿18 分钟前
JavaScript--WebAPI查缺补漏(二)
开发语言·前端·javascript·html·ecmascript
@解忧杂货铺4 小时前
前端vue如何实现数字框中通过鼠标滚轮上下滚动增减数字
前端·javascript·vue.js
苹果酱05676 小时前
「Mysql优化大师一」mysql服务性能剖析工具
java·vue.js·spring boot·mysql·课程设计
真的很上进9 小时前
如何借助 Babel+TS+ESLint 构建现代 JS 工程环境?
java·前端·javascript·css·react.js·vue·html
web1309332039810 小时前
vue elementUI form组件动态添加el-form-item并且动态添加rules必填项校验方法
前端·vue.js·elementui
supermapsupport11 小时前
iClient3D for Cesium在Vue中快速实现场景卷帘
前端·vue.js·3d·cesium·supermap
m0_7482548812 小时前
vue+elementui实现下拉表格多选+搜索+分页+回显+全选2.0
前端·vue.js·elementui
噢,我明白了13 小时前
同源策略:为什么XMLHttpRequest不能跨域请求资源?
javascript·跨域
sanguine__13 小时前
APIs-day2
javascript·css·css3
苹果醋313 小时前
Golang的文件加密工具
运维·vue.js·spring boot·nginx·课程设计