APIs
LoadingBar
参数 说明 类型 默认值 必传 containerClass 加载条容器的类名 string undefined false containerStyle 加载条容器的样式 CSSProperties {} false loadingBarSize 加载条大小,单位 px
number 2 false colorLoading 加载中颜色 string ‘#1677ff’ false colorFinish 加载完成颜色 string ‘#1677ff’ false colorError 加载错误颜色 string ‘#ff4d4f’ false to 加载条的挂载位置,可选:元素标签名(例如 body
)或者元素本身 string | HTMLElement ‘body’ false
Methods
名称 说明 类型 start 开始加载的回调函数 (from = 0, to = 80) => void finish 结束加载的回调函数 () => void error 出现错误的回调函数 () => void
创建加载条组件LoadingBar.vue
< script setup lang= "ts" >
import { ref, nextTick } from 'vue'
import type { CSSProperties } from 'vue'
interface Props { containerClass? : string containerStyle? : CSSProperties loadingBarSize? : number colorLoading? : string colorFinish? : string colorError? : string to? : string | HTMLElement
}
withDefaults ( defineProps < Props> ( ) , { containerClass: undefined , containerStyle : ( ) => ( { } ) , loadingBarSize: 2 , colorLoading: '#1677ff' , colorFinish: '#1677ff' , colorError: '#ff4d4f' , to: 'body'
} )
const showLoadingBar = ref ( false )
const loadingBarRef = ref ( )
const loadingStarted = ref ( false )
const loadingFinishing = ref ( false )
const loadingErroring = ref ( false )
async function init ( ) { showLoadingBar. value = false loadingFinishing. value = false loadingErroring. value = false
}
async function start ( from = 0 , to = 80 , status: 'starting' | 'error' = 'starting' ) { loadingStarted. value = true await init ( ) if ( loadingFinishing. value) { return } showLoadingBar. value = true await nextTick ( ) if ( ! loadingBarRef. value) { return } loadingBarRef. value. style. transition = 'none' loadingBarRef. value. style. maxWidth = ` ${ from } % ` void loadingBarRef. value. offsetWidth loadingBarRef. value. className = ` loading-bar loading-bar- ${ status} ` loadingBarRef. value. style. transition = '' loadingBarRef. value. style. maxWidth = ` ${ to} % `
}
async function finish ( ) { if ( loadingFinishing. value || loadingErroring. value) { return } if ( loadingStarted. value) { await nextTick ( ) } loadingFinishing. value = true if ( ! loadingBarRef. value) { return } loadingBarRef. value. className = 'loading-bar loading-bar-finishing' loadingBarRef. value. style. maxWidth = '100%' void loadingBarRef. value. offsetWidth showLoadingBar. value = false
}
function error ( ) { if ( loadingFinishing. value || loadingErroring. value) { return } if ( ! showLoadingBar. value) { void start ( 100 , 100 , 'error' ) . then ( ( ) => { loadingErroring. value = true } ) } else { loadingErroring. value = true if ( ! loadingBarRef. value) { return } loadingBarRef. value. className = 'loading-bar loading-bar-error' loadingBarRef. value. style. maxWidth = '100%' void loadingBarRef. value. offsetWidthshowLoadingBar. value = false }
}
function onAfterEnter ( ) { if ( loadingErroring. value) { showLoadingBar. value = false }
}
async function onAfterLeave ( ) { await init ( )
}
defineExpose ( { start, finish, error
} )
< / script>
< template> < Teleport : disabled= "!to" : to= "to" > < Transition name= "fade-in" @ after - enter= "onAfterEnter" @ after - leave= "onAfterLeave" > < div v- show= "showLoadingBar" class = "m-loading-bar-container" : class = "containerClass" : style= "containerStyle" > < divref= "loadingBarRef" class = "loading-bar" : style= "`--loading-bar-size: ${loadingBarSize}px; --color-loading: ${colorLoading}; --color-finish: ${colorFinish}; --color-error: ${colorError}; max-width: 100%;`" > < / div> < / div> < / Transition> < / Teleport>
< / template>
< style lang= "less" scoped>
. fade- in - enter- active { transition: all 0 . 3s cubic- bezier ( 0.4 , 0 , 0.2 , 1 ) ;
}
. fade- in - leave- active { transition: all 0 . 8s cubic- bezier ( 0.4 , 0 , 0.2 , 1 ) ;
}
. fade- in - enter- from,
. fade- in - leave- to { opacity: 0 ;
}
. m- loading- bar- container { z- index: 9999 ; position: fixed; top: 0 ; left: 0 ; right: 0 ; height: var ( -- loading- bar- size) ; . loading- bar { width: 100 % ; transition: max- width 4s linear, background 0 . 2s linear; height: var ( -- loading- bar- size) ; border- radius: var ( -- loading- bar- size) ; } . loading- bar- starting { background: var ( -- color- loading) ; } . loading- bar- finishing { background: var ( -- color- finish) ; transition: max- width 0 . 2s linear, background 0 . 2s linear; } . loading- bar- error { background: var ( -- color- error) ; transition: max- width 0 . 2s linear, background 0 . 2s linear; }
}
< / style>
其中引入使用了以下组件:
Vue3间距(Space) Vue3按钮(Button)
在要使用的页面引入
< script setup lang= "ts" >
import LoadingBar from './LoadingBar.vue'
import { ref } from 'vue'
const loadingBar = ref ( )
const disabled = ref ( true )
const localCardRef = ref ( )
const localLoadingBar = ref ( )
const customLoadingBar = ref ( )
function handleStart ( ) { loadingBar. value. start ( ) disabled. value = false
}
function handleFinish ( ) { loadingBar. value. finish ( ) disabled. value = true
}
function handleError ( ) { disabled. value = true loadingBar. value. error ( )
}
< / script>
< template> < div> < h1> { { $route. name } } { { $route. meta. title } } < / h1> < h2 class = "mt30 mb10" > 基本使用< / h2> < Space> < Button type= "primary" @ click = "handleStart" > 开始< / Button> < Button : disabled= "disabled" @ click = "handleFinish" > 结束< / Button> < Button type= "danger" @ click = "handleError" > 报个错< / Button> < / Space> < LoadingBar ref= "loadingBar" / > < h2 class = "mt30 mb10" > 局部加载条< / h2> < div class = "m-container" ref= "localCardRef" > < Space> < Button type= "primary" @ click = "localLoadingBar.start()" > Start< / Button> < Button @ click = "localLoadingBar.finish()" > Finish< / Button> < Button type= "danger" @ click = "localLoadingBar.error()" > Error< / Button> < / Space> < / div> < LoadingBar ref= "localLoadingBar" : container- style= "{ position: 'absolute' }" : to= "localCardRef" / > < h2 class = "mt30 mb10" > 自定义加载条样式< / h2> < Space> < Button type= "primary" @ click = "customLoadingBar.start()" > Start< / Button> < Button @ click = "customLoadingBar.finish()" > Finish< / Button> < Button type= "danger" @ click = "customLoadingBar.error()" > Error< / Button> < / Space> < LoadingBarref= "customLoadingBar" : loading- bar- size= "5" color- loading= "#2db7f5" color- finish= "#52c41a" color- error= "magenta" / > < / div>
< / template>
< style lang= "less" scoped>
. m- container { position: relative; display: flex; align- items: center; height: 200px; padding: 16px 24px; border: 1px solid #d9d9d9;
}
< / style>