-
效果图
<template> <!-- --> <div class='stepBar' v-if="list"> <dl> <dd v-for="(item, index) in list" :key="index" :class="{ actafter: index + 1 <= selected }" class="al"> <div class="round" :class="{ act: index + 1 <= selected }">{{ index + 1 }}</div> <div class="text" :class="{ acttext: index + 1 <= selected }" > <div class="borderText" > <span class="textpe" v-if="item.type == 1"> {{ item.name }}</span> <span class="texttype" v-if="item.type == 2"> {{ item.name }}</span> </div> <div class="tip" v-if="item.type == 2"> <span v-for="(items,i) in item.chan" :key="i">{{ items.name }}</span> </div> </div> </dd> </dl> </div> </template> <script> export default { name: 'stepBar', props: { list: { typeof: Array, default: () => [ { type: 2, name: '步骤基本1', chan: [ { name: '双方基本信息' }, { name: '双方基本信息2' }, ] }, { type: 1, name: '步骤基本2' }, { type: 1, name: '步骤基本3' }, { type: 1, name: '步骤基本4' } ] }, selected: { typeof: Number, String, default: 2 }, }, components: {}, data() { return { }; }, computed: { // 主体设置 }, watch: {}, methods: { }, //生命周期 - 创建完成(可以访问当前this实例) created() { }, //生命周期 - 挂载完成(可以访问DOM元素) mounted() { }, beforeCreate() { }, //生命周期 - 创建之前 beforeMount() { }, //生命周期 - 挂载之前 beforeUpdate() { }, //生命周期 - 更新之前 updated() { }, //生命周期 - 更新之后 beforeDestroy() { }, //生命周期 - 销毁之前 destroyed() { }, //生命周期 - 销毁完成 activated() { }, //如果页面有keep-alive缓存功能,这个函数会触发 } </script> <style scoped lang="less"> dl, dd { margin: 0; padding: 0; } .stepBar { position: relative; dl { display: flex; position: relative; dd { position: relative; width: 100%; height: 100%; display: flex; flex-direction: column; align-items: center; .round { position: relative; width: 20px; height: 20px; border-radius: 50%; background-color: #b0bfd2; text-align: center; display: flex; justify-content: center; align-items: center; color: #fff; font-size: 12px; z-index: 1; box-shadow: 0px 12px 16px rgba(0, 0, 0, 0.3); } .text { margin: 8px 0px; font-size: 14px; position: relative; } .borderText{ display: flex; justify-content: center; } .texttype { position: relative; margin: 5px 0px; } .textpe { position: relative; margin: 27px 0px; } .texttype::before { content: ""; display: inline-block; width: 20%; height: 100%; border-top: 1px dashed #bcd5f2; border-left: 1px dashed #bcd5f2; position: absolute; left: -32%; top: 50%; } .texttype::after { content: ""; display: inline-block; width: 20%; height: 100%; border-top: 1px dashed #bcd5f2; border-right: 1px dashed #bcd5f2; position: absolute; right: -32%; top: 50%; } .tip{ position: relative; span{ position: relative; display: inline-block; margin: 0px 10px; font-size: 12px; } span:first-child::after { content: ''; position: absolute; border-style: solid; border-color: transparent; border-width: 3px 0 3px 5px; border-left-color: #2971c9; right: -13px; top: 5px; } } } .al::after { position: absolute; content: ''; top: 8px; left: 0; width: 100%; height: 5px; background-color: #bcd5f2; } .al:first-child::after { left: 50%; } .al:last-child::after { width: 50%; } .actafter::after { background-color: #2971c9 !important; } .act { background-color: #2971c9 !important; box-shadow: 0px 12px 16px rgba(41, 113, 201, 0.3) !important; } .acttext { color: #2971c9 !important; } } }</style>