VLoading.ts 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. import { createApp, h } from 'vue'
  2. import Loading from '../components/VLoading'
  3. export const VLoading = {
  4. mounted(el: any, binding: any) {
  5. let options = {}
  6. const target = el.getAttribute('target')
  7. if (target) {
  8. options = {
  9. target: `${target}`
  10. }
  11. } else {
  12. if (el.id) {
  13. options = {
  14. target: `#${el.id}`
  15. }
  16. } else {
  17. el.id = `loading-target-${Math.random().toString(36).slice(2, 9)}`
  18. options = {
  19. target: `#${el.id}`
  20. }
  21. }
  22. }
  23. options = {
  24. ...options,
  25. isLoadingBackground: el.getAttribute('isLoadingBackground') || false
  26. }
  27. const app = createApp({
  28. render() {
  29. return h(Loading, { loading: binding.value, ...options })
  30. }
  31. })
  32. const newDiv = document.createElement('div')
  33. el.appendChild(newDiv) // 将 Loading 组件的根元素添加到目标元素中
  34. const instance = app.mount(newDiv)
  35. el.style.position = 'relative' // 确保父元素有相对定位
  36. el.instance = instance
  37. el.newDiv = newDiv // 保存对新 div 的引用
  38. el.component = app // 保存 Vue 应用实例
  39. },
  40. updated(el: any, binding: any) {
  41. if (binding.value !== binding.oldValue) {
  42. // 卸载旧的组件
  43. if (el.component) {
  44. el.component.unmount()
  45. el.component = null
  46. }
  47. // 移除旧的 div 元素
  48. if (el.newDiv) {
  49. el.removeChild(el.newDiv)
  50. el.newDiv = null
  51. }
  52. // 创建新的 Vue 应用实例和 div 元素
  53. const target = el.id || `loading-target-${Math.random().toString(36).substr(2, 9)}`
  54. const app = createApp({
  55. render() {
  56. return h(Loading, { loading: binding.value, target: `#${target}` })
  57. }
  58. })
  59. const newDiv = document.createElement('div')
  60. el.appendChild(newDiv)
  61. const instance = app.mount(newDiv)
  62. el.instance = instance
  63. el.newDiv = newDiv // 更新对新 div 的引用
  64. el.component = app // 更新 Vue 应用实例
  65. }
  66. },
  67. unmounted(el: any) {
  68. if (el.newDiv) {
  69. el.removeChild(el.newDiv) // 移除剩余的 div 元素
  70. }
  71. if (el.component) {
  72. el.component.unmount() // 卸载 Vue 应用实例
  73. }
  74. }
  75. }