文章目录
-
- 概要
- 技术名词解释
- 技术细节
- 小结
概要
首先看效果
技术名词解释
- uniapp
- uni组件
技术细节
首先看需求是步骤条,然后看组件中没有自己想要的步骤条,那么就的自己去写
一、HTML部分
<template> <view class="mainStepOut"> <view class="stepOut"> <ul class="stepul"> <li class="stepItem"> <!-- 大圈部分 --> <view v-for="(item,index) in list" :key="index"> <!-- 小圈部分 --> <view class="step1" v-if="item.step.length>0" v-for="(item1,index1) in item.step" :key="index1"> <!-- 此处为小圆圈 --> <view :class="index1 === 0 ?(index===0?'iconSmall active':'iconSmall'):'iconSmall'"></view> <!-- 模拟步骤条连接线(判断列表到最后一项后把线隐藏) --> <view class="line" :style="'height:'+stepnewheight[index1]+'px'" v-if="index !== list.length - 1 && item.title1!==''"> </view> <!-- 主题内容 --> <view class="stepStatus1" :id="'stepStatus1'+index1"> <view :class="index1 === 0 ?(index===0?'titlecolor':'title'):'title'"> <text>{{item1.title}}</text> <text>{{item1.date}}</text> </view> <view class="annotation"> <view class="item_person" v-html="item1.content"> <!-- {{item1.content}} --> </view> </view> </view> </view> <view class="step1" v-if="item.title1!==''"> <!-- 此处为圆圈 --> <view :class="item.step.length!==0?'icon':(index == 0 ?'icon1':'icon')"></view> <!-- 模拟步骤条连接线(判断列表到最后一项后把线隐藏) --> <view class="line" :style="'height:'+newheight[index]+'px'" v-if="index !== list.length - 1"> </view> <!-- 主题内容 --> <view class="stepStatus" :id="'stepStatus'+index"> <view :class="item.step.length!==0 ? 'title':(index == 0 ?'titlecolor':'title')"> <view>{{item.title1}}</view> <text v-if="item.title2">{{item.title2}}</text> <text>{{item.date}}</text> </view> <view class="annotation"> <view class="item_person" v-html="item.content"> </view> </view> </view> </view> </view> </li> </ul> </view> </view> </template>
复制
二、CSS部分
<style lang="scss" scoped> .mainStepOut{ height: 100%; overflow-y: auto; } .stepOut { height: 100%; padding-top: 40rpx; width: 100%; display: flex; justify-content: space-between; .stepul { list-style: none; width: 100%; margin-left: -20rpx; .stepItem { width: 100%; font-size: 32rpx; position: relative; border-left: #d7d7d7; // display: flex; .step1 { display: flex; width: 100%; // height: 200rpx; font-size: 32rpx; position: relative; border-left: #d7d7d7; } .icon { width: 32rpx; height: 32rpx; flex: 0 0 32rpx; border-radius: 50%; background: #fff; border: 4rpx solid #d7d7d7; position: relative; z-index: 888; } .icon1 { width: 38rpx; height: 38rpx; border-radius: 50%; flex: 0 0 38rpx; right: 1.5px; border: 4rpx solid #2E88FF; position: relative; z-index: 888; background-color: #fff; } .icon1:before { content: ""; position: absolute; top: 5rpx; left: 5rpx; width: calc(100% - 8rpx); height: calc(100% - 8rpx); background-color: #2E88FF; border-radius: 50%; flex: 0 0 calc(100% - 8rpx); } .iconSmall { width: 21rpx; height: 21rpx; border-radius: 50%; flex: 0 0 21rpx; background: #fff; // border: 4rpx solid #d7d7d7; position: relative; left: 2.8px; background: #808080; z-index: 888; margin-right: 10rpx; } .active { background-color: #2E88FF; border: 0; } .line { position: absolute; top: 12rpx; // left: 13rpx; left: 14rpx; width: 4rpx; // height: 200rpx; background-color: #e2e2e2; z-index: 111; } .stepStatus { width: 100%; padding: 0 25rpx; background: #FAFAFA; margin-bottom: 26rpx; margin-left: 15rpx; margin-right: 15rpx; padding-top: 10rpx; margin-top: -16rpx; padding-bottom: 10rpx; border-radius: 18rpx; .annotation { font-size: 25rpx; color: #b0b0b0; } } .stepStatus1 { width: 100%; padding: 0 25rpx; background: #FAFAFA; margin-bottom: 26rpx; margin-left: 15rpx; margin-right: 15rpx; padding-top: 10rpx; margin-top: -16rpx; padding-bottom: 10rpx; border-radius: 18rpx; .annotation { font-size: 25rpx; color: #b0b0b0; } } // 未进行 .title { display: flex; color: #808080; margin-bottom: 10rpx; view { font-size: 30rpx; // font-weight: 700; margin-right: 18rpx; } text { font-size: 25rpx; display: flex; flex-direction: column-reverse; justify-self: end; margin-right: 20rpx; } } // 已进行 .titlecolor { display: flex; color: #2E88FF; margin-bottom: 10rpx; view { color: #2E88FF; font-size: 30rpx; // font-weight: 700; margin-right: 18rpx; } text { font-size: 25rpx; display: flex; flex-direction: column-reverse; justify-self: end; margin-right: 20rpx; } } } } } </style>
复制
因为有小圈还有大圈所有上面的主体部分的进行判断,很好理解的上面都有注释,当你的数组长度最大时就不显示线条,反之显示
现在几乎实现了整体部分,但是bug出现了,就是你的部分如果高的话就会把下面部分挤出去,线条就不能正常链接了,这个问题怎么解决呢!!!别着急看下面
三、bug问题解决
咱们可以通过uniapp中的Api进行判断它的高度进行给线段设置高度(uni.createSelectorQuery)
uni.createSelectorQuery()
返回一个 SelectorQuery
对象实例。可以在这个实例上使用 select
等方法选择节点,并使用 boundingClientRect
等方法选择需要查询的信息。
Tips:
- 使用
uni.createSelectorQuery()
需要在生命周期mounted
后进行调用。 - 默认需要使用到
selectorQuery.in
方法。
measureViewHeight() { for (let i = 0; i < this.list.length; i++) { uni.createSelectorQuery() .in(this) .select(`#stepStatus${i}`) .boundingClientRect(rect => { // console.log(`Div1的高度为:${rect.height}px`); let sum = rect.height + 9 this.newheight.push(sum) }) .selectViewport() .scrollOffset() .exec(); } for (let i = 0; i < this.list.length; i++) { for (let j = 0; j < this.list[i].step.length; j++) { uni.createSelectorQuery() .in(this) .select(`#stepStatus1${j}`) .boundingClientRect(rect => { // console.log(`Div的高度为:${rect.height}px`); let sum = rect.height + 9 this.stepnewheight.push(sum) }) .selectViewport() .scrollOffset() .exec(); } } },
复制
重新命名两个数组进行存储主体的高度,进行在html部分进行循环输出,我为什么在后面加了一个9呢,因为我进行测试输出的高度总比我想要的高度小,所有我给他们固定加了9px。可以根据自己的需求进行加减
<!-- 模拟步骤条连接线(判断列表到最后一项后把线隐藏) --> <view class="line" :style="'height:'+stepnewheight[index1]+'px'" v-if="index !== list.length - 1 && item.title1!==''"> </view>
复制
四、完整代码
<template> <view class="mainStepOut"> <view class="stepOut"> <ul class="stepul"> <li class="stepItem"> <!-- 大圈部分 --> <view v-for="(item,index) in list" :key="index"> <!-- 小圈部分 --> <view class="step1" v-if="item.step.length>0" v-for="(item1,index1) in item.step" :key="index1"> <!-- 此处为小圆圈 --> <view :class="index1 === 0 ?(index===0?'iconSmall active':'iconSmall'):'iconSmall'"></view> <!-- 模拟步骤条连接线(判断列表到最后一项后把线隐藏) --> <view class="line" :style="'height:'+stepnewheight[index1]+'px'" v-if="index !== list.length - 1 && item.title1!==''"> </view> <!-- 主题内容 --> <view class="stepStatus1" :id="'stepStatus1'+index1"> <view :class="index1 === 0 ?(index===0?'titlecolor':'title'):'title'"> <text>{{item1.title}}</text> <text>{{item1.date}}</text> </view> <view class="annotation"> <view class="item_person" v-html="item1.content"> <!-- {{item1.content}} --> </view> </view> </view> </view> <view class="step1" v-if="item.title1!==''"> <!-- 此处为圆圈 --> <view :class="item.step.length!==0?'icon':(index == 0 ?'icon1':'icon')"></view> <!-- 模拟步骤条连接线(判断列表到最后一项后把线隐藏) --> <view class="line" :style="'height:'+newheight[index]+'px'" v-if="index !== list.length - 1"> </view> <!-- 主题内容 --> <view class="stepStatus" :id="'stepStatus'+index"> <view :class="item.step.length!==0 ? 'title':(index == 0 ?'titlecolor':'title')"> <view>{{item.title1}}</view> <text v-if="item.title2">{{item.title2}}</text> <text>{{item.date}}</text> </view> <view class="annotation"> <view class="item_person" v-html="item.content"> </view> </view> </view> </view> </view> </li> </ul> </view> </view> </template> <script> import Api from '@/untils/api.js' export default { data() { return { list: [], //模拟数据 newheight: [], stepnewheight: [] }; }, created() { }, mounted() { this.getProgressByAccountNo() this.$nextTick(() => { setTimeout(() => { this.measureViewHeight() }, 320) }) }, methods: { measureViewHeight() { for (let i = 0; i < this.list.length; i++) { uni.createSelectorQuery() .in(this) .select(`#stepStatus${i}`) .boundingClientRect(rect => { // console.log(`Div1的高度为:${rect.height}px`); let sum = rect.height + 9 this.newheight.push(sum) }) .selectViewport() .scrollOffset() .exec(); } for (let i = 0; i < this.list.length; i++) { for (let j = 0; j < this.list[i].step.length; j++) { uni.createSelectorQuery() .in(this) .select(`#stepStatus1${j}`) .boundingClientRect(rect => { // console.log(`Div的高度为:${rect.height}px`); let sum = rect.height + 9 this.stepnewheight.push(sum) }) .selectViewport() .scrollOffset() .exec(); } } }, // 进度接口 getProgressByAccountNo() { //接口 } } }; </script> <style lang="scss" scoped> .mainStepOut{ height: 100%; overflow-y: auto; } .stepOut { height: 100%; padding-top: 40rpx; width: 100%; display: flex; justify-content: space-between; .stepul { list-style: none; width: 100%; margin-left: -20rpx; .stepItem { width: 100%; font-size: 32rpx; position: relative; border-left: #d7d7d7; // display: flex; .step1 { display: flex; width: 100%; // height: 200rpx; font-size: 32rpx; position: relative; border-left: #d7d7d7; } .icon { width: 32rpx; height: 32rpx; flex: 0 0 32rpx; border-radius: 50%; background: #fff; border: 4rpx solid #d7d7d7; position: relative; z-index: 888; } .icon1 { width: 38rpx; height: 38rpx; border-radius: 50%; flex: 0 0 38rpx; right: 1.5px; border: 4rpx solid #2E88FF; position: relative; z-index: 888; background-color: #fff; } .icon1:before { content: ""; position: absolute; top: 5rpx; left: 5rpx; width: calc(100% - 8rpx); height: calc(100% - 8rpx); background-color: #2E88FF; border-radius: 50%; flex: 0 0 calc(100% - 8rpx); } .iconSmall { width: 21rpx; height: 21rpx; border-radius: 50%; flex: 0 0 21rpx; background: #fff; // border: 4rpx solid #d7d7d7; position: relative; left: 2.8px; background: #808080; z-index: 888; margin-right: 10rpx; } .active { background-color: #2E88FF; border: 0; } .line { position: absolute; top: 12rpx; // left: 13rpx; left: 14rpx; width: 4rpx; // height: 200rpx; background-color: #e2e2e2; z-index: 111; } .stepStatus { width: 100%; padding: 0 25rpx; background: #FAFAFA; margin-bottom: 26rpx; margin-left: 15rpx; margin-right: 15rpx; padding-top: 10rpx; margin-top: -16rpx; padding-bottom: 10rpx; border-radius: 18rpx; .annotation { font-size: 25rpx; color: #b0b0b0; } } .stepStatus1 { width: 100%; padding: 0 25rpx; background: #FAFAFA; margin-bottom: 26rpx; margin-left: 15rpx; margin-right: 15rpx; padding-top: 10rpx; margin-top: -16rpx; padding-bottom: 10rpx; border-radius: 18rpx; .annotation { font-size: 25rpx; color: #b0b0b0; } } // 未进行 .title { display: flex; color: #808080; margin-bottom: 10rpx; view { font-size: 30rpx; // font-weight: 700; margin-right: 18rpx; } text { font-size: 25rpx; display: flex; flex-direction: column-reverse; justify-self: end; margin-right: 20rpx; } } // 已进行 .titlecolor { display: flex; color: #2E88FF; margin-bottom: 10rpx; view { color: #2E88FF; font-size: 30rpx; // font-weight: 700; margin-right: 18rpx; } text { font-size: 25rpx; display: flex; flex-direction: column-reverse; justify-self: end; margin-right: 20rpx; } } } } } </style>
复制
接口数据结构
小结
如果感觉还不错的话可以关注博主哦,会持续更新的,谢谢~谢谢