Vben-admin学习(三)——v-loading自定义指令实现

        在学习vben-admin源码过程中,看到v-loading指令,实现在元素上加上v-loading就能展示元素的加载状态。记录一下实现过程。

一、定义一个加载页面组件






二、定义一个创建LoadingPage组件的函数

import { createVNode, defineComponent, h, reactive, render, VNode } from 'vue'
import BasicLoading from './index.vue'
import { LoadingProps } from './types'
export const createLoading = (props?: LoadingProps, target?: HTMLElement) => {
  let vm: Nullable = null
  const data = reactive({
    tip: '',
    loading: true,
    ...props
  })

  const LoadingWrap = defineComponent({
    render() {
      return createVNode(BasicLoading, { ...data })
    }
  })
  vm = createVNode(LoadingWrap)
  const open = (target: HTMLElement = document.body) => {
    if (!vm) return
    render(vm, target)
  }
  const close = () => {
    if (vm?.el && vm.el.parentNode) {
      vm.el.parentNode.removeChild(vm.el)
    }
  }
  const setTip = (tip: string) => {
    data.tip = tip
  }
  const setLoading = (loading: boolean) => {
    data.loading = loading
  }

  if (target) {
    open(target)
  }

  return {
    vm,
    close,
    open,
    setTip,
    setLoading,
    get loading() {
      return data.loading
    },
    get $el() {
      return vm?.el as HTMLElement
    }
  }
}

三、定义指令

import { createLoading } from '@/components/basicLoading/createLoading'

type ExtendHTMLElement = HTMLElement & {
  instance?: any
}

export const loading: Directive = {
  mounted(el: ExtendHTMLElement, binding) {
    const tip = el.getAttribute('loading-tip')
    const background = el.getAttribute('loading-background')
    const size = el.getAttribute('loading-size')
    const theme = el.getAttribute('loading-theme')
    const color = el.getAttribute('loading-color')
    const fullscreen = !!binding.modifiers.fullscreen
    const instance = createLoading(
      {
        tip: tip || undefined,
        background: background || undefined,
        size: (size || 'large') as SizeEnum,
        loading: !!binding.value,
        absolute: !fullscreen,
        theme: (theme || 'dark') as 'light' | 'dark',
        color: color || undefined
      },
      fullscreen ? document.body : el
    )
    el.instance = instance
  },
  updated(el, binding) {
    const instance = el.instance
    if (binding.oldValue !== binding.value) {
      // if (!instance.loading) {
      console.log('hdfgdsfd')
      instance.setLoading(binding.value)
      // }
    }
  },
  unmounted(el) {
    el.instance.close()
  }
}

四、调用

  

你可能感兴趣的:(Vben学习记录,前端相关,vue.js)