基于vue+ts的平行四边形进度条

基于vue+ts的平行四边形进度条


效果图
// 子组件部分

<template>
    <div style="position: relative">
        <!-- 带正负 -->
        <div v-if="data.isCenter" style="position: relative">
       		// 绑定id 做唯一标识
            <div class="progress-bar-wrap" :id="data.id">
            	// 对于初始结点0在中间的进度条,可以分割左右两部分,分别进行渲染
            	// 左侧底部部分,如果值为负数,那么左侧底部为传进来的bg颜色
            	// 如果值为正数,那么左侧背景色为透明,渲染border-color为传进来的bg颜色
                <div 
                    class="progress-bar-container-left-wrap" 
                    :style="{'background': data.value > 0 ? '#fff0': data.bg, 
                             'border-color': data.value > 0 ? data.bg : '#fff0'
                            }"
                ></div>
                // 右侧底图部分 背景色和border-color的渲染规则与正好相反
                <div 
                    class="progress-bar-container-right-wrap" 
                    :style="{'background': data.value > 0 ? data.bg : '#fff0',
                             'border-color': data.value > 0 ? '#fff0' : data.bg
                            }"
                ></div>
            </div>
            // 真实值的渲染,渲染父组件传过来的valueBG,以及值对应的宽度(百分比)
            <div class="progress-value-wrap" 
                :style="{'background': data.valueBG, width: widthPer}" 
                :class="data.value > 0 ? 'isRightCenter' : 'isLeftCenter'"
            >
                <div class="progress-value-container-wrap"></div>
            </div>
            // 中间的数字0,判断是在左侧展示还是右侧展示
            <div 
                :class="data.value > 0 ? 'center-num-right' : 'center-num-left'" 
                class="center-num"
            >0</div>
        </div>
        <!-- 从左侧为0开始计数 -->
        <div v-if="!data.isCenter">
        	// 底层背景色的渲染
            <div class="progress-bar-wrap" :style="{'background': data.bg}">
                <div class="progress-bar-container-wrap"></div>
            </div>
            // 值的渲染
            <div class="progress-value-wrap" :style="{'background': data.valueBG, width: widthPer}">
                <div class="progress-value-container-wrap"></div>
            </div>
        </div>
    </div>
</template>

js部分

<script lang="ts">
    import { Component, Prop, Vue, Watch } from "vue-property-decorator"

    @Component({})
    export default class RealInfo extends Vue {
        @Prop({
            required: true,
            default: {
                id: 'id',
                bg: '#8a2be2', // 底色
                valueBG: '#eeeeee', // 值部分的底色
                isCenter: true, // 判断初始值0 是在中心还是左侧, true代表在中心, false代表在左侧
                value: 0 // 值
            }
        })data
		
		// 计算值所占的宽度
        get widthPer() {
            let absVal = Math.abs(this.data.value)
            
            switch(true) {
                case val < 100: 
                    return absVal  + '%'
                    break;
                case val < 1000:
                    return absVal  / 1000 * 100 + '%'
                    break;
                case val < 10000: 
                    return absVal  / 10000 * 100 + '%'
                    break;
            }
        }
    }
</script>

css部分

<style lang="less" scoped>
    .progress-bar-wrap {
        width: 100%;
        height: 20px;
        transform: skewX(-10deg);
        .progress-bar-container-left-wrap,
        .progress-bar-container-right-wrap {
            display: inline-block;
            width: 50%;
            height: 100%;
            border: 1px solid black;
        }
        .progress-bar-container-wrap {
            width: 20%;
            height: 100%;
        }
    }
    .progress-value-wrap {
        position: absolute;
        z-index: 9;
        height: 20px;
        top: 0;
        transform: skewX(-10deg);
        .progress-value-container-wrap {
            transform: skewX(10deg);
        }
    }

    .isRightCenter {
        left: 48%;
    }
    .isLeftCenter {
        right: 50%;
    }
    .center-num {
        position: absolute;
        top: 50%;
        transform: translate(-50%, -50%);
        color: #ffffff;
    }
    .center-num-right {
        right: 50%;
    }
    .center-num-left {
        left: 55%;
    }
</style>

父组件

<template>
	<ProgressBar  :data="videoXProp" />
	<ProgressBar  :data="videoYProp" />
	<ProgressBar  :data="videoZProp" />
</template>
<script lang="ts">
    import { Component,  Prop,  Vue, Watch } from "vue-property-decorator"
    import ProgressBar from '@/components/chart/progressBar.vue'
    
    @Component({
        components: { ProgressBar }
    })
    export default class RealInfo extends Vue {
    	videoXProp: any = {
            id: 'videoXId',
            bg: '#AD9358',
            valueBG: '#F8B05F',
            isCenter: true,
            value: 45
        }
        
		videoYProp: any = {
            id: 'videoYId',
            bg: '#AD9358',
            valueBG: '#F8B05F',
            isCenter: true,
            value: -30
        }

        videoZProp: any = {
            id: 'videoYId',
            bg: '#AD9358',
            valueBG: '#F8B05F',
            isCenter: false,
            value: 34
        }
	}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值