useIframe.ts 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. import {Ref, ref, nextTick, onDeactivated, onActivated} from "vue";
  2. import {useResizeObserver} from "@vueuse/core";
  3. import sleep from "@/utils/sleep";
  4. export const iframeList: Ref<IframeOption[]> = ref([])
  5. export declare type IframeOption = {
  6. src: string;
  7. show?: boolean,
  8. ref?: Ref<HTMLIFrameElement>,
  9. style?: any
  10. }
  11. export function useIframe(div: Ref<HTMLDivElement>, opt: IframeOption) {
  12. opt.show = true
  13. opt.style = {}
  14. const index = iframeList.value.push(opt) - 1
  15. useResizeObserver(div, (entries) => {
  16. const entry = entries[0]
  17. const {width, height} = entry.contentRect
  18. if (width === 0 && height === 0) {
  19. iframeList.value[index].show = false
  20. return
  21. }
  22. iframeList.value[index].style.width = width + 'px';
  23. iframeList.value[index].style.height = height + 'px';
  24. nextTick(async () => {
  25. await sleep(300)
  26. const rect = div.value.getBoundingClientRect();
  27. if (rect.top === 0 && rect.left === 0) {
  28. iframeList.value[index].show = false
  29. return
  30. }
  31. iframeList.value[index].style.top = rect.top + 'px';
  32. iframeList.value[index].style.left = rect.left + 'px';
  33. iframeList.value[index].show = true
  34. })
  35. })
  36. onActivated(() => {
  37. iframeList.value[index].show = true
  38. })
  39. onDeactivated(() => {
  40. iframeList.value[index].show = false
  41. })
  42. function stop() {
  43. iframeList.value.splice(index, 1)
  44. }
  45. return {
  46. stop
  47. }
  48. }