Skip to content

进度条

本插件最终效果

属性指南

属性说明类型默认值必填
percentage终点number100
width宽度number126
height高度number126
type进度条类型line或者circle或者dashboardcricle
strokeWidth进度条的宽度number6
textinside进度条显示文字内置在进度条(仅仅 type 为 line 有效)booleanfalse
status进度条当前状态successexceptionwarning-
indeterminate是否为动画进度条booleanfalse
duration控制动画进度条速度和条纹进度条流动速度number3000
color进度条背景色 (会覆盖 status 状态颜色)string或者function或者Array#409eff
showtext是否显示进度条文字内容booleantrue
strokelinecapcircle/dashboard 类型路径两端的形状butt 或者 round 或者 squareround
format指定进度条文字内容(percentage: number) => string-
striped在进度条上增加条纹booleanfalse
stripedflow让进度条上的条纹流动起来booleanfalse
isAnimation是否仅仅是个动画 (需要配套 time 和 getResult 使用)booleanfalse
time动画完成的时间 (需要配套 time 和 getResult 使用)number3000(毫秒)
getResult回调事件 (需要配套 time 和 getResult 使用)Function-

Slots

插槽名说明类型
default自定义内容-

插件代码

vue
<template>
  <div class="demo-progress">
    <el-progress
      :percentage="presult"
      :type="props.type"
      :stroke-width="props.strokeWidth"
      :text-inside="props.textinside"
      :status="props.status"
      :indeterminate="props.indeterminate"
      :duration="props.duration"
      :color="props.color"
      :width="props.width"
      :show-text="props.showtext"
      :stroke-linecap="props.strokelinecap"
      :format="props.format"
      :striped="props.striped"
      :striped-flow="props.stripedflow"
    >
      <slot></slot>
    </el-progress>
  </div>
</template>

<script setup lang="ts">
import { ref, withDefaults, onMounted } from "vue";
import { type IChooseProcess } from "@/types/chooseProcess/type";

const emits = defineEmits<{
  (e: "getResult", val: Boolean): void;
}>();

const props = withDefaults(
  defineProps<{
    percentage: number;
    width: number;
    height: number;
    type?: string;
    strokeWidth?: number;
    textinside?: boolean;
    status?: string;
    indeterminate?: boolean;
    duration?: number;
    color?: string | Function | { color: string; percentage: number }[];
    showtext?: boolean;
    strokelinecap?: string;
    format?: (percentage: number) => string;
    striped?: boolean;
    stripedflow?: boolean;
    // 自己添加的纯属动画
    isAnimation?: boolean;
    time?: number;
  }>(),
  {
    percentage: 10,
    type: "circle",
    strokeWidth: 6,
    textinside: false,
    status: "",
    indeterminate: false,
    duration: 3000,
    color: "#409eff",
    width: 126,
    height: 126,
    showtext: true,
    strokelinecap: "round",
    format: (percentage: number) => `${percentage}%`,
    striped: false,
    stripedflow: false,
    isAnimation: false,
    time: 3000,
  }
);

const width = ref<string>(props.width + "px");
const height = ref<string>(props.height + "px");
const presult = ref<number>(0);
const getProcess = () => {
  if (props.isAnimation) {
    // 目的地
    let result = presult.value == 0 ? 100 : presult.value;
    // 每米用多少秒
    let t = props.time / result;
    let timer = setInterval(() => {
      presult.value += 1;
      if (presult.value >= result) {
        presult.value = result;
        emits("getResult", true);
        clearInterval(timer);
      }
    }, t);
  }
};

onMounted(() => {
  presult.value = JSON.parse(JSON.stringify(props.percentage));
  getProcess();
});
</script>

<style scoped lang="scss">
.demo-progress {
  ::v-deep(.el-progress--line) {
    width: v-bind(width) !important;
    height: v-bind(height) !important;
    svg {
      width: 100%;
      height: 100%;
    }
  }
  ::v-deep(.el-progress-circle) {
    width: v-bind(width) !important;
    height: v-bind(height) !important;
    svg {
      width: 100%;
      height: 100%;
    }
  }
}
</style>

页面调用

vue
<template>
  <div>
    <yj-process
      :percentage="percentage2"
      :width="width"
      :height="height"
      :isAnimation="isAnimation2"
      @getResult="getResult"
    >
      <div style="color: red">测试开始中间3434343</div>
    </yj-process>

    <yj-process
      :percentage="percentage"
      :width="width"
      :height="height"
      :isAnimation="isAnimation"
      :textinside="textinside"
      :strokeWidth="strokeWidth"
      :status="status"
      :type="type"
    >
      <div style="color: red">测试开始中间3434343</div>
    </yj-process>

    <yj-process
      :percentage="percentage"
      :width="width"
      :height="height"
      :isAnimation="isAnimation"
      :textinside="textinside"
      :strokeWidth="strokeWidth"
      :status="status"
      :type="type"
      :indeterminate="indeterminate"
      :duration="duration"
    >
      <div style="color: red">测试开始中间3434343</div>
    </yj-process>
  </div>
</template>

<script setup lang="ts">
import { ref } from "vue";
const isAnimation2 = ref(true);
const percentage2 = ref(0);
const percentage = ref(10);
const width = ref(200);
const height = ref(200);
const isAnimation = ref(false);
const textinside = ref(true);
const strokeWidth = ref(10);
const status = ref("exception");
const type = ref("line");
const indeterminate = ref(true);
const duration = ref(5);

const getResult = (result) => {
  console.log(result);
  if (result) {
    console.log("已经完成了");
  }
};
</script>

<style scoped></style>