mirror of
https://github.com/element-plus/element-plus.git
synced 2026-03-13 07:51:17 +08:00
* refactor(loading): refactored loading component * refactor(loading): use render & createVNode instead of createApp Co-authored-by: Ryan <ryanzhao2128@gmail.com>
118 lines
2.9 KiB
TypeScript
118 lines
2.9 KiB
TypeScript
import { createVNode, reactive, ref, toRefs, h, Transition, render, VNode } from 'vue'
|
|
import { removeClass } from '@element-plus/utils/dom'
|
|
import type { ILoadingCreateComponentParams, ILoadingInstance } from './loading'
|
|
|
|
export function createLoadingComponent({ options , globalLoadingOption }: ILoadingCreateComponentParams): ILoadingInstance {
|
|
let vm: VNode = null
|
|
let afterLeaveTimer: Nullable<number> = null
|
|
|
|
const afterLeaveFlag = ref(false)
|
|
const data = reactive({
|
|
...options,
|
|
originalPosition: '',
|
|
originalOverflow: '',
|
|
visible: options.hasOwnProperty('visible') ? options.visible : true,
|
|
})
|
|
|
|
function setText(text: string) {
|
|
data.text = text
|
|
}
|
|
|
|
function destorySelf() {
|
|
const target = data.parent
|
|
if(!target.vLoadingAddClassList) {
|
|
removeClass(target, 'el-loading-parent--relative')
|
|
removeClass(target, 'el-loading-parent--hidden')
|
|
}
|
|
if (vm.el && vm.el.parentNode) {
|
|
vm.el.parentNode.removeChild(vm.el)
|
|
}
|
|
}
|
|
|
|
function close() {
|
|
const target = data.parent
|
|
target.vLoadingAddClassList = null
|
|
if (data.fullscreen) {
|
|
globalLoadingOption.fullscreenLoading = undefined
|
|
}
|
|
afterLeaveFlag.value = true
|
|
clearTimeout(afterLeaveTimer)
|
|
|
|
afterLeaveTimer = window.setTimeout(() => {
|
|
if (afterLeaveFlag.value) {
|
|
afterLeaveFlag.value = false
|
|
destorySelf()
|
|
}
|
|
}, 400)
|
|
data.visible = false
|
|
}
|
|
|
|
function handleAfterLeave() {
|
|
if (!afterLeaveFlag.value) return
|
|
afterLeaveFlag.value = false
|
|
destorySelf()
|
|
}
|
|
|
|
const componetSetupConfig = {
|
|
...toRefs(data),
|
|
setText,
|
|
close,
|
|
handleAfterLeave,
|
|
}
|
|
|
|
const elLoadingComponent = {
|
|
name: 'ElLoading',
|
|
setup() {
|
|
return componetSetupConfig
|
|
},
|
|
render() {
|
|
const spinner = h('svg', {
|
|
class: 'circular',
|
|
viewBox: '25 25 50 50',
|
|
}, [
|
|
h('circle', { class: 'path', cx: '50', cy: '50', r: '20', fill: 'none' }),
|
|
])
|
|
|
|
const noSpinner = h('i', { class: this.spinner })
|
|
|
|
const spinnerText = h('p', { class: 'el-loading-text' }, [this.text])
|
|
|
|
return h(Transition, {
|
|
name: 'el-loading-fade',
|
|
onAfterLeave: this.handleAfterLeave,
|
|
},{
|
|
default: () => h('div', {
|
|
style: {
|
|
backgroundColor: this.background || '',
|
|
display: this.visible ? 'inherit' : 'none',
|
|
},
|
|
class: [
|
|
'el-loading-mask',
|
|
this.customClass,
|
|
this.fullscreen ? 'is-fullscreen' : '',
|
|
],
|
|
}, [
|
|
h('div', {
|
|
class: 'el-loading-spinner',
|
|
}, [
|
|
!this.spinner ? spinner : noSpinner,
|
|
this.text ? spinnerText : null,
|
|
]),
|
|
]),
|
|
})
|
|
},
|
|
}
|
|
|
|
vm = createVNode(elLoadingComponent)
|
|
|
|
render(vm, document.createElement('div'))
|
|
|
|
return {
|
|
...componetSetupConfig,
|
|
vm,
|
|
get $el(){
|
|
return vm.el as HTMLElement
|
|
},
|
|
}
|
|
}
|