vue3 实现自定义指令 v-loading(基于 ant design 的 spin 组件实现)

想法: 本来是想简单的通过对指令的绑定节点设置相对定位然后在其子级创建loading组件覆盖原有元素,但考虑到强制改变节点样式可能对原有样式产生干扰,于是有了新的想法。

​
import { render, h } from 'vue'
import { Spin } from 'ant-design-vue';
const mount = (el: HTMLElement): void => {
  el.childNodes.forEach((item: any) => {
    item.style && (item.style.opacity = '0')
  })
  // 绑定节点下创建子节点
  let parent: HTMLElement | null = el.querySelector('#__LOADING_PARENT__')
  if (!parent) {
    parent = document.createElement('div')
    parent.style.position = 'relative'
    parent.id = '__LOADING_PARENT__'
    if (el.firstChild) {
      el.insertBefore(parent, el.firstChild)
    } else {
      el.appendChild(parent)
    }
  }
  parent.style.opacity = '1'
  const elStyle = window.getComputedStyle(el, null)
  const style = {
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
    position: 'absolute',
    flexDirection: 'column',
    left: `-${elStyle.paddingLeft}`,
    width: `${el.clientWidth}px`,
    height: `${el.clientHeight}px`,
    backgroundColor: 'rgba(0, 0, 0, 0.3)',
    opacity: 1,
    zIndex: 1000
  }
  render(h(Spin, { class: 'directive-loading', tip: '加载中...', size: 'large', style }), parent)
}
const unmount = (el: HTMLElement) => {
  el.childNodes.forEach((item: any) => {
    item.style && (item.style.opacity = '1')
  })
  const loading: HTMLElement | null = el.querySelector('#__LOADING_PARENT__')
  if (!loading) return
  el.removeChild(loading)
}
export default {
  // 在绑定元素的父组件 及他自己的所有子节点都挂载完成后调用
  mounted: (el: HTMLElement, binding: any) => {
    binding.value && mount(el)
  },
  // 在绑定元素的父组件 及他自己的所有子节点都更新后调用
  updated: (el: HTMLElement, binding: any) => {
    binding.value ? mount(el) : unmount(el)
  }
}

​

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值