Skip to content

进度条

架构

bash
├── src
   ├── components
   ├── chooseProcess
      ├── lib (引入的第三方库)
    └── xxx.json
      ├── src (源码)
   ├── index.vue
      ├── index.ts

index.ts

ts
import { type App } from 'vue'
import chooseProcess from './src/index.vue'

// 让这个组件可以通过use的形式使用
export default {
    install(app: App) {
        app.component('YJ-choose-process', chooseProcess)
    }
}

interface/chooseProcess/type.ts

  • 定义chooseProcess组件的props类型
ts
export interface ChooseProcess {
    // 终点
    percentage: number
    // 是否有动画效果
    isAnimate: boolean
    // 动画时长(毫秒)
    time: number
    // 进度条宽度
    width: string
    // 进度条高度
    height: string
}

hooks/chooseProcess/useProcess.ts

ts
import { ref } from 'vue'
import { type ChooseProcess } from '@/interfaces/chooseProcess/type'
export const useProcess = () => {
    // 获取进度
    const p = ref(0)
    // 模拟进度
    const getProcess = (propsdata: ChooseProcess) => {
        if (propsdata.isAnimate) {
            // 规定时间内加载完成
            let t = Math.ceil(propsdata.time / propsdata.percentage)
            let timer = setInterval(() => {
                p.value += 1
                if (p.value >= propsdata.percentage) {
                    p.value = propsdata.percentage
                    clearInterval(timer)
                }
            }, t)
        }
    }
    // 挂载
    return {
        p,
        getProcess
    }
}

components/chooseProcess/src/index.vue

vue
<template>
    <div class="demo-progress">
        <el-progress :percentage="p" v-bind="$attrs" />
    </div>
</template>

<script setup lang="ts">
    import { ref, withDefaults, onMounted } from 'vue'

    import { type ChooseProcess } from '@/interfaces/chooseProcess/type'

    import { useProcess } from '@/hooks/chooseProcess/useProcess'

    // 获取父元素的数据

    const props = withDefaults(
        defineProps<{
            data: ChooseProcess
        }>(),
        {
            data: () => ({
                percentage: 100,
                isAnimate: true,
                time: 3000,
                width: '200px',
                height: '200px'
            }),
            required: false
        }
    )

    // 定义宽度和高度

    const width = ref(props.data.width)
    const height = ref(props.data.height)

    // 实例化
    const { p, getProcess } = useProcess()

    // 挂载

    onMounted(() => {
        getProcess(props.data)
    })
</script>

<style lang="scss" scoped>
    .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>

pages/chooseProcess/index.vue

vue

<template>
    <div>
        进度条
        <YJ-choose-process :data="data"></YJ-choose-process>
        <YJ-choose-process type="dashboard" color="#167089" :data="data2"></YJ-choose-process>
    </div>
</template>

<script setup lang="ts">
    import { ref } from 'vue'
    const data = ref({
        percentage: 100,
        isAnimate: true,
        time: 3000
    })
    const data2 = ref({
        percentage: 100,
        isAnimate: true,
        time: 3000,
        width: '200px',
        height: '200px'
    })
</script>

<style scoped></style>