Vue3 基于Element Plus 线型进度条 el-progress 二次封装

7 篇文章 0 订阅
2 篇文章 0 订阅

项目背景

ui设计师在设计线型进度条的时候在进度条底部加上了一个显示数据的面板,但是Element Plus提供的format和slot不满足此次的需求,就自己封装了一下。

请添加图片描述

代码

<template>
    <div class="progress">
        <el-progress :percentage="progressNumber" :show-text="showTextFn" />
        <div ref="panel" v-show="showPlan" class="panel">{{ planTextStr }}</div>
    </div>
</template>
<script lang="ts" setup>
import { computed, ref, onMounted, watch } from 'vue';
const props = defineProps({
    // 百分比,必填 0-100
    percentage: {
        type: Number,
        default() {
            return 0
        }
    },
    // 进度条类型
    type: {
        type: String,
        default() {
            return 'line' // line/circle/dashboard
        }
    },
    // stroke-width
    strokeWidth: {
        type: Number,
        default() {
            return 6
        }
    },
    // 是否显示进度条文字内容
    showText: {
        type: Boolean,
        default() {
            return true
        }
    },
    // 是否显示信息面板
    showPlan: {
        type: Boolean,
        default() {
            return false
        }
    },
    // 面板显示文字
    planText: String,
})

const progressNumber = computed(() => {
    if (props.percentage > 100) return 100;
    else if (props.percentage < 0) return 0;
    else return props.percentage;
})

const showTextFn = computed(() => {
    if (props.showPlan) return false
    return props.showText
})

const panel = ref<any>(null);
const panelHeight = ref<string>('0px');
const translateX = ref<string>('0%');
const left = computed(() => `${progressNumber.value}%`);

const planTextStr = computed(() => {
    if (props.planText) return props.planText;
    else return `${progressNumber.value}%`
})

const showPlanType = computed(() => {
    if (props.type === 'line') return props.showPlan;
    else return false
})

onMounted(() => {
    if (showPlanType.value) {
        panelHeight.value = `${panel.value.offsetHeight + 5}px`;
        const widthHalf = panel.value.offsetWidth / 2; // 面板宽度的一半
        if (progressNumber.value > widthHalf && progressNumber.value < (100 - widthHalf)) translateX.value = '-50%';
        else  translateX.value = '0%';
    }
})
// 监听百分比变化 修改面板translateX
watch(
    progressNumber,
    (val, preVal) => {
        if (!showPlanType.value) return
        const widthHalf = panel.value.offsetWidth / 2; // 面板宽度的一半
        if (progressNumber.value > widthHalf && progressNumber.value < (100 - widthHalf)) translateX.value = '-50%';
        else if (progressNumber.value >= (100 - widthHalf)) translateX.value = '-100%';
        else  translateX.value = '0%';
    }
)

</script>
.progress {
    position: relative;
}

.progress::after {
    content: '';
    display: inline-block;
    height: v-bind(panelHeight);;
}

.progress .panel {
    max-width: 100%;
    white-space: nowrap;/*内容超宽后禁止换行显示*/
    overflow: hidden;/*超出部分隐藏*/
    text-overflow:ellipsis;/*文字超出部分以省略号显示*/
    position: absolute;
    left: v-bind(left);
    bottom: 0;
    z-index: 1;
    background: #EAEDF4;
    border-radius: 4px;
    padding: 0 6px;
    height: 22px;
    line-height: 22px;
    white-space: nowrap;
    transform: translateX(v-bind(translateX));
    transition: all .5s;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DevilAngelia

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值