Files
Notebook-StarNet/杂项/ResizeObserverComponent.md
T
2024-12-13 11:17:19 +08:00

2.0 KiB
Raw Blame History

import {
  defineComponent,
  watch,
  onMounted,
  onBeforeUnmount,
  h,
  getCurrentInstance,
  type PropType,
} from 'vue-demi'
import ResizeObserver from './ResizeObserver'
import type { IOptions } from './types'


// const component = {
//   name: 'Home',
//   props:{
//     data: String,
//   },
//   setup(props, context){
//     // props.data
//     // context.attrs    context.slots    context.emit 
//   }
// }

export default defineComponent({
  name: 'ResizeObserverComponent',
  props: {
    target: [String, Object] as PropType<string | HTMLElement>,
    disabled: Boolean as PropType<boolean>,
    immediate: Boolean as PropType<boolean>,
    delay: {
      type: Number as PropType<number>,
      default: 150
    }
  },
  setup(props, { slots }) {
    let ro: ResizeObserver | null = null
    watch(() => props.disabled, (val) => {
      if (val) {
        ro?.disconnect()
      } else {
        ro?.observe()
      }
    })
    onMounted(() => {
      // const { target, disabled, limiter, wait } = toRefs(props)
      // 拿到当前组件的实例(注意已挂载)
      const vm = getCurrentInstance()?.proxy

      // 先用$el
      let $el: HTMLElement = vm?.$el as HTMLElement

      if (props.target) {
        if (typeof props.target === 'string') {
          $el = document.querySelector(props.target) as HTMLElement
        } else if (props.target instanceof HTMLElement) {
          $el = props.target
        }
      }
      const options: IOptions = {
        delay: props.delay,
        immediate: props.immediate,
        resize: (data, elem) => {
          vm?.$emit('resize', data, elem)
        }
      }
      ro = new ResizeObserver($el, options)
    })
    // 销毁 ResizeObserver实例
    onBeforeUnmount(() => {
      if (ro) {
        ro.destroy()
      }
    })
    
    // 如果有单个子元素则直接渲染子元素
    const defaultContent = slots.default?.()
    return () => (
      (defaultContent && defaultContent.length === 1)
        ? defaultContent[0]
        : h('div', defaultContent)
    )
  }
})