200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > vue+css左边三角形的矩形完成自定义流程图(可扩展)

vue+css左边三角形的矩形完成自定义流程图(可扩展)

时间:2019-03-17 14:44:09

相关推荐

vue+css左边三角形的矩形完成自定义流程图(可扩展)

组件用到所有图标都来自阿里云iconfont

注意事项:

1、这里的三角形是两个三角形的叠加,因为只有一个div,所以采用叠加伪类元素和绝对定位的方式实现;

2、绘制第一个 &::before三角形, &::after绘制第二个三角形,第一个三角形给个背景色,第二个三角形给背景色和矩形颜色一样。

效果图

1、页面

<template><div class="custom-map-for-approval"><h2 class="map-title">审批进度</h2><template v-if="nodeList && nodeList.length > 0"><div class="map-node" v-for="(item, index) of nodeList" :key="index"><div :class="['map-left-line', {'send': item.type=='notifier'}]"><!-- 发起节点状态 --><template v-if="item.type=='start'"><span v-if="Array.isArray(item.person)" :title="item.person[0].staffName" class="line-name">{{item.person[0].staffName.substring(0,2)}}</span><!-- 是否完成图标 --><span class="line-complete-icon"><i class="icon2_ icon2_gou complete-icon"></i></span></template><!-- 已审批状态 --><template v-else-if="item.reason =='approve_agree'||item.reason =='approve_refuse'"><i class="icon2_ icon2_workflow-center line-icon"></i><!-- 是否完成图标 --><span class="line-complete-icon"><i class="icon2_ icon2_gou complete-icon"></i></span></template><!-- 待审批状态 --><template v-else-if="item.type =='approver'&&!item.reason"><i class="icon2_ icon2_workflow-center line-icon"></i></template><!-- 抄送状态 --><template v-else-if="item.type=='notifier'"><i class="icon2_ icon2_faqishenpi line-icon"></i><!-- 是否完成图标 --><span class="line-complete-icon"><i class="icon2_ icon2_gou complete-icon"></i></span></template><!-- 待重审状态 --><template v-else-if="item.type=='approve_wait'"><i class="icon2_ icon2_faqishenpi line-icon"></i></template><!-- 其他状态 --><template v-else-if="['approve_recall','approve_revoke'].includes(item.type)"><i class="icon2_ icon2_workflow-center line-icon"></i><!-- 是否完成图标 --><span class="line-complete-icon"><i class="icon2_ icon2_gou complete-icon"></i></span></template></div><div class="map-right-content"><div class="item-cell"><div class="item-label"><span class="label-name">{{item.title}}</span><span class="label-time">{{item.time}}</span></div><div class="item-node"><span v-if="Array.isArray(item.person)" :title="item.person[0].staffName" :class="['node-name']">{{item.person[0].staffName}}</span><!-- 发起节点状态 --><span v-if="item.type=='start'" class="is-complete-icon"><i class="icon2_ icon2_gou complete-icon"></i></span><!-- 已完成审批状态 --><span v-if="item.reason =='approve_agree'" class="is-complete-icon"><i class="icon2_ icon2_gou complete-icon"></i></span><!-- 已拒绝状态 --><span v-if="item.reason =='approve_refuse'" class="is-complete-icon"><i class="icon2_ icon2_gou complete-icon"></i></span><!-- 其他状态 --><span v-if="['approve_recall','approve_revoke'].includes(item.type)" class="is-complete-icon"><i class="icon2_ icon2_gou complete-icon"></i></span><div :class="['node-status']" v-if="item.type=='start'">发起</div><div :class="['node-status', 'agree']" v-if="item.reason =='approve_agree'">已审批</div><div :class="['node-status', 'reject']" v-if="item.reason =='approve_refuse'">已拒绝</div><div :class="['node-status', 'pend']" v-if="item.type =='approver'&&!item.reason">待审批</div><div :class="['node-status', 'send']" v-if="item.type=='notifier'">抄送</div><div :class="['node-status', 'reject']" v-if="item.type=='approve_recall'">退回</div><div :class="['node-status', 'recall']" v-if="item.type=='approve_revoke'">撤回</div><div :class="['node-status', 'reject']" v-if="item.type=='approve_wait'">重审</div></div><div class="item-status-content" v-if="item.type !== 'start'">{{item.message}}</div><!-- 当前节点如果有图片和文件 --><div class="item-centent-imgs img_box" v-if="item.photos&&item.photos.length > 0"><viewer class="img_list"><img v-for="(img) in item.photos" :key="img.url" title="点击图片查看详情" :src="showImages(img.url)" alt="" ></viewer></div><div v-for="(files) in item.files" :key="files.url" class="item-centent-files file_list"><i v-if="files.suffix=='zip'" class="icon iconzip"></i><i v-else-if="files.suffix=='xls'||files.suffix=='xlsx'" class="icon iconxlsx"></i><i v-else-if="files.suffix=='doc'||files.suffix=='docx'" class="icon icondoc"></i><i v-else-if="files.suffix=='pdf'" class="icon iconpdf"></i><i v-else-if="files.suffix=='txt'" class="icon icontxt"></i><i v-else class="icon iconmoren"></i><div class="preview" title="点击可预览文件" @click="previewFile(files)" > {{files.name}}</div><div class="preview_file" title="点击可下载" @click="downloadFile(files)">下载</div></div></div></div></div></template><!-- 文件预览组件 --><file-preview v-if="preFlag" :fileTitle="fileTitle" :excleUrl="excleUrl" :fileType="fileType" :url="fileUrl" @close="closeModal"></file-preview></div></template><script>import FilePreview from "~components/preview/file-preview";import {showImage } from '~script/utils'export default {name:'custom-approval-map',components:{FilePreview},data(){return{preFlag: false, //预览组件默认关闭fileUrl: '',// 文件预览加载地址fileType: '', // 文件类型fileTitle: '', // 文件标题excleUrl: '', // excle表格url}},props:{nodeList:{type: Array,require: true,default: function(){return []}}},watch:{nodeList:{handler(n, o){// console.log(n, 444);},immediate: true}},methods:{// 图片展示showImages(url){return showImage(url) || ''},//下载文件downloadFile(val){// url,data,params,contentType,mark,responsetypethis.$ajax.get(this.$api.file.downloadFile,{url: val.url},{},0,'','blob').then(res =>{DownFile.Down(res)}).catch(err => console.log(err))},// 文件预览previewFile(val){if (['rar','zip'].includes(val.url.split('.')[1])) {this.$Message.warning('压缩文件暂时不支持预览哦~')return}// 提取文件类型let type = val.url.split('.')this.excleUrl = valthis.fileUrl = `/api${this.$api.file.onlinePreview}?url=${val.url}&access_token=${LocalStore.get('access_token')}`this.fileType = type[1]this.fileTitle = val.namethis.preFlag = true},// 预览组件关闭closeModal(val) {this.preFlag = val;},}}</script><style lang="less">@import url('./style.less');</style>

2、css代码

// 自定义流程图.custom-map-for-approval{.map-title{font-size: 16px;font-weight: bold;color: #333;padding: 20px 20px 20px 0;margin-top: 15px;border-top: 1px solid #999999;}.map-node{display: flex;position: relative;.map-left-line{width: 40px;height: 40px;border-radius: 50%;background-color: #2d8cf0;font-size: 8px;color: #fff;text-align: center;line-height: 40px;overflow: hidden;.line-name{font-size: 12px;}.line-icon{font-size: 22px;}.line-complete-icon{display: block;width: 16px;height: 16px;border-radius: 50%;text-align: center;line-height: 16px;background-color: #3fba73;position: absolute;left: 25px;top: 25px;.complete-icon{color: #fff;}}&.send{background-color: #FFBA02; }// 自定义流程虚线&::before{content: '';display: block;width: 2px;height: 100%;background-color: #CDCDCD;// z-index: -1;position: absolute;left: 18px;top: 40px;}}&:last-child{.map-left-line{&::before{display: none;}}}.map-right-content{position: relative;width: 100%;margin: 12px 0 0 17px;.item-cell{position: relative;top: -22px;left: 10px;background-color: #fff;border-radius: 6px;padding: 12px 16px;margin-right: 16px;box-shadow: 1px 1px 4px #93c1f3;.item-label{line-height: 1;display: flex;justify-content: space-between;.label-name{font-size: 15px;font-weight: bold;color: #333;}.label-time{font-size: 13px;font-weight: bold;color: #B9B9B9;.label-status{padding: 0 10px;}}}.item-node{display: flex;align-items: center;margin: 10px 0;.node-name{width: 30px;height: 30px;border-radius: 50%;background-color: #2d8cf0;font-size: 8px;color: #fff;text-align: center;line-height: 30px;overflow: hidden;position: relative;}.is-complete-icon{display: block;width: 16px;height: 16px;border-radius: 50%;text-align: center;line-height: 16px;background-color: #3fba73;position: absolute;left: 35px;top: 55px;.complete-icon{color: #fff;}}.node-status{color: #666;padding-left: 10px;&.agree{// 同意样式color: #3fba73;}&.reject{// 拒绝样式color: #E76060;}&.pend{// 待审批样式color: #fa795e;}&.recall{// 撤回color: orange;}&.send{// chaosocolor: #2d8cf0;}}}.item-centent-files{align-items: center;margin: 6px 0 0 0;}.item-status-content{line-height: 1.5;}// 绘制向左三角形,borer-left不做操作,其他加右边颜色和上下透明即可&::before{content: '';width: 0;height: 0;border-top: 10px solid transparent;border-right: 12px solid #edf6ff;border-bottom: 11px solid transparent;// 滤镜(filter)中的drop-shadow()// drop-shadow才是真正意义上的投影,而box-shadow只是盒阴影filter: drop-shadow(0px 0px 1px #93c1f3);position: absolute;left: -13px;top: 20px;}// 覆盖第一个三角形,形成边框&::after{content: '';width: 0;height: 0;border-top: 9px solid transparent;border-right: 11px solid #fff;border-bottom: 10px solid transparent;position: absolute;left: -11px;top: 21px;}}}}}.img_box{display:flex;margin-top: 10px;.img_list{display:flex;margin-top: 10px;img{margin-right:15px;border-radius:6px;cursor: pointer;width: 80px;height: 80px;}}}.file_list{display: flex;flex-wrap: wrap;margin: 6px 0 0 38px;.iconzip, .iconxlsx, .icondoc, .iconpdf, .icontxt, .iconmoren{font-size:30px;margin-right: 10px;}.iconzip{color:#BDC3C9;}.iconxlsx{color: #E74D3C;}.icondoc{color: #5497D7;}.iconpdf{color: #30CC71;}.icontxt{color: #F1C411;}.iconmoren{color: #5497D7;}.preview{cursor: pointer;&:hover{color: #169BD5;}}.preview_file{margin-left: 20px;color: #169BD5;cursor: pointer;&:hover{color: red;}}}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。