进度条
架构
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>