Vue学习篇3_自定义时间线timeline
1.效果展示2.代码实现父页面子页面timeline.vue子页面card.vue父页面<div v-for="(v, i) in uni_data" :key="'id' + i" class="year-item"><timeline :time-data="v"><template slot="cardSlot" slot-scope="scope">&l
·
1.效果展示
2.代码
实现
- 父页面
- 子页面timeline.vue
- 子页面card.vue
父页面
<div v-for="(v, i) in uni_data" :key="'id' + i" class="year-item">
<timeline :time-data="v">
<template slot="cardSlot" slot-scope="scope">
<!--这里采用作用域插槽-可以自己自定义卡片样式-->
<card :card-data="scope.card"></card>
</template>
</timeline>
</div>
子页面timeline.vue
<template>
<div class="timeline-main">
<!--年月标题-->
<div class="timeline-title">
{{ timeData.yearData }}
<i
:class="showCards ? 'el-icon-arrow-down' : 'el-icon-arrow-right'"
@click="showCards = !showCards"
></i>
</div>
<ul class="timeline-body">
<!--时间线顶部圆点-->
<li class="timeline-item-head">
<div class="item-node"></div>
<div class="item-tail"></div>
</li>
<!--时间线内容-->
<template v-if="showCards">
<li
v-for="(mouthItem, i) in timeData.mouthData"
:key="'mm' + i"
class="timeline-item"
>
<div class="item-left">
<div class="item-left-data">{{ mouthItem.dateData }}</div>
<div class="item-left-total">
<div class="item-left-total-text">
共{{ mouthItem.dateArr.length }}条
</div>
<div class="item-left-total-end"></div>
</div>
</div>
<div class="item-tail"></div>
<div class="item-node"></div>
<div class="item-content">
<slot name="cardSlot" v-for="v in mouthItem.dateArr" :card="v"></slot>
</div>
</li>
</template>
<!--时间线尾部圆点-->
<li class="timeline-item-foot">
<div class="item-node"></div>
<div class="item-tail"></div>
</li>
</ul>
</div>
</template>
<script>
export default {
name: "Timeline",
props: {
timeData: {
type: Object,
default: () => ({}),
},
},
data() {
return {
showCards: true,
};
},
};
</script>
<style scoped lang="less">
.timeline-main {
padding: 0 0 0 20px;
.timeline-title {
margin-bottom: 10px;
font-weight: bold;
i {
cursor: pointer;
}
}
.timeline-body {
margin: 0;
font-size: 14px;
list-style: none;
// 顶尾圆圈
.timeline-item-head,
.timeline-item-foot {
position: relative;
height: 15px;
.item-tail {
position: absolute;
left: 45px;
height: 100%;
border-left: 2px solid #e4e7ed;
}
.item-node {
position: absolute;
left: 42px;
width: 8px;
height: 8px;
background-color: #e4e7ed;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
}
}
.timeline-item-foot {
.item-node {
top: 14px;
}
}
// 时间线主体内容
.timeline-item {
position: relative;
padding-bottom: 10px;
.item-left {
position: absolute;
top: 13px;
left: -9px;
.item-left-data {
font-weight: bold;
line-height: 20px;
}
.item-left-total {
display: flex;
font-size: 12px;
.item-left-total-text {
padding: 0 3px;
line-height: 20px;
color: #ffffff;
background: #409eff;
}
.item-left-total-end {
width: 0;
height: 0;
border-top: 10px solid transparent;
border-left: 6px solid #409eff;
border-bottom: 10px solid transparent;
}
}
}
.item-tail {
position: absolute;
left: 45px;
height: 100%;
border-left: 2px solid #e4e7ed;
}
.item-node {
position: absolute;
top: 38px;
left: 41px;
width: 6px;
height: 6px;
background-color: #ffffff;
border: 2px solid #409eff;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
}
.item-content {
position: relative;
padding-top: 15px;
padding-left: 60px;
// top: -3px;
}
}
}
}
</style>
子页面card.vue
<template>
<div class="item-content-card" @click="goDetail()">
<div class="time-title" :class="statusStyle(cardData.status)">
<i class="el-icon-time"></i>
<!-- {{ cardData.createTime.slice(-8) }} -->
<div class="item-status"><b>{{ formatStatus(cardData.status) }}</b></div>
</div>
<div class="time-content">
<div class="time-content-no">
<div class="time-content-no-circle" :class="{'time-content-delete' : cardData.type!=1}"></div>
{{ cardData.workNo }}
</div>
<div class="time-content-name">
<span>{{ cardData.name }}</span>
新增/导入/删除
<div v-if="showRevoke()" class="opera-icon-back" title="撤销" @click.stop="revokeWorkFlow"></div>
<div v-if="showRevoke() && cardData.status == 4" class="opera-icon-edit" title="编辑" @click.stop="editWorkFlow"></div>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'TheWorkNoteCard',
props: {
cardData: {
type: Object,
default: () => ({})
}
},
methods: {
// 跳转详情页面
goDetail() {
this.$router.push({});
},
// 显示撤销
showRevoke() {
// 判断符合条件的逻辑
},
// 撤销
revokeWorkFlow() {
},
// 编辑被驳回
editWorkFlow() {
},
statusStyle(v) {
if (String(v) === '2') {
return 'time-status-unreview';
} else if (String(v) === '3') {
return 'time-status-success';
} else if (String(v) === '4' || String(v) === '5') {
return 'time-status-back';
} else {
return 'time-status-unreview';
}
},
formatStatus(v) {
if (String(v) === '2') { // 待审核
return '待审核';
} else if (String(v) === '3') { // 通过
return '通过';
} else if (String(v) === '4') { // 驳回
return '驳回';
} else if (String(v) === '5') { // 撤销
return '撤销';
} else {
return '--';
}
},
}
};
</script>
<style scoped lang="less">
.item-content-card {
cursor: pointer;
border-radius: 4px;
background-color: #f7f9fa;
margin-bottom: 10px;
.time-title {
position: relative;
box-sizing: border-box;
height: 50px;
padding: 15px;
border-bottom: 1px solid #e4e4e4;
i {
font-size: 16px;
}
.item-status {
position: absolute;
font-size: 12px;
top: 13px;
right: 0;
width: 40px;
text-align: center;
z-index: 1;
transform: rotate(45deg)
}
&:after {
content: "";
position: absolute;
top: 0;
right: 0;
border-style: solid;
border-width: 25px 25px 25px 25px;
width: 0px;
height: 0px;
}
}
.time-status-unreview {
.item-status {
color: #409EFF;
}
&:after {
border-color: #d3e7fb #d3e7fb transparent transparent;
}
}
.time-status-success {
.item-status {
color: #67C23A;
}
&:after {
border-color: #dbeed4 #dbeed4 transparent transparent;
}
}
.time-status-back {
.item-status {
color: #E6A23C;
}
&:after {
border-color: #f4e7d4 #f4e7d4 transparent transparent;
}
}
.time-content {
padding: 15px;
.time-content-no {
margin-bottom: 10px;
.time-content-no-circle {
width: 10px;
height: 10px;
display: inline-block;
background-color: #8ec850;
border-radius: 50%;
margin-right: 6px;
}
.time-content-delete {
background-color: #666666;
}
}
.time-content-name {
line-height: 20px;
padding-left: 20px;
span {
margin-right: 20px;
}
.opera-icon-back {
margin-left: 30px;
display: inline-block;
width: 18px;
height: 18px;
cursor: pointer;
//background: url('../images/rollback.png') no-repeat;
background-size: 18px;
&:hover {
// background: url('../images/rollback_h.png') no-repeat;
background-size: 18px;
}
}
.opera-icon-edit {
margin-left: 5px;
display: inline-block;
width: 18px;
height: 18px;
cursor: pointer;
//background: url('../images/edit.png') no-repeat;
background-size: 18px;
&:hover {
//background: url('../images/edit_h.png') no-repeat;
background-size: 18px;
}
}
}
}
&:hover {
box-shadow: 0px 0px 4px rgba(0, 0, 0, 0.176470588235294)
}
}
</style>
更多推荐
已为社区贡献5条内容
所有评论(0)