远方的灯塔 - 专注于服务端技术分享 远方的灯塔 - 专注于服务端技术分享
首页
  • Java SE
  • Struts2
  • Hibernate
  • MyBatis
  • JAX-WS
  • 并发
  • 分布式
  • Git
  • 《C程序设计语言》
心情随笔
  • 文章分类
  • 文章标签
  • 文章归档
友情链接
关于我
GitHub (opens new window)

Terwer Green

一个后端老菜鸟
首页
  • Java SE
  • Struts2
  • Hibernate
  • MyBatis
  • JAX-WS
  • 并发
  • 分布式
  • Git
  • 《C程序设计语言》
心情随笔
  • 文章分类
  • 文章标签
  • 文章归档
友情链接
关于我
GitHub (opens new window)
  • JavaScript

  • Vue3

    • Vue3 配合 Element-Plus 和 iframe-resizer 完美实现抽屉 Drawer 和 iframe
      • 环境准备
      • iframe
      • 使用
      • 效果预览
  • 前端开发
  • Vue3
terwer
2024-02-28
目录

Vue3 配合 Element-Plus 和 iframe-resizer 完美实现抽屉 Drawer 和 iframe

通过 Vue 指令实现自动调整 iframe 大小,包括抽屉占位和页面使用的示例。使用 iframe-resizer 库监听 iframe 内容变化并自动调整高度,有效解决了页面内嵌 iframe 的高度适配问题。

# 环境准备

pnpm install vue lodash element-plus iframe-resizer
pnpm install @types/iframe-resizer -D
1
2

# iframe

新建文件 src/utils/directives/iframeResize.ts​

import { Directive, DirectiveBinding, nextTick } from "vue"
import iframeResize from "iframe-resizer/js/iframeResizer"
import { isDev } from "~/src/utils/constants.ts"
import _ from "lodash"

interface ResizableHTMLElement extends HTMLElement {
  iFrameResizer?: {
    removeListeners: () => void
  }
}

const resize: Directive = {
  mounted(el: HTMLElement, binding: DirectiveBinding) {
    const options = binding.value || {
      log: isDev,
      checkOrigin: false,
      iframeResizerEnable: true,
      autoResize: false,
      warningTimeout: 30000,
    }

    el.addEventListener("load", () => {
      nextTick(() => {
        // 获取最大宽度
        const maxWidth = _.max([
          document.body.offsetWidth,
          document.body.scrollWidth,
          document.documentElement.offsetWidth,
          document.documentElement.scrollWidth,
        ])

        // 设置元素高度为最大宽度
        el.style.height = maxWidth + "px"
        iframeResize(options, el)
      })
    })
  },
  unmounted(el: HTMLElement) {
    const resizableEl = el as ResizableHTMLElement

    if (resizableEl.iFrameResizer) {
      resizableEl.iFrameResizer.removeListeners()
    }
  },
}

export default resize
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

# 使用

抽屉占位

  <!-- 抽屉占位 -->
    <el-drawer v-model="showDrawer" size="85%" direction="rtl" :destroy-on-close="true">
      <DrawerBoxBridge :src="drawerSrc" />
    </el-drawer>
1
2
3
4

iframe

<!--suppress ALL -->
<script setup lang="ts">
const props = defineProps({
  src: {
    type: String,
    default: "",
  },
})
</script>

<template>
  <div>
    <iframe v-resize width="100%" :src="src" frameborder="0"></iframe>
  </div>
</template>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

页面使用

const showDrawer = ref(false)
const drawerSrc = ref("")

const handleQuick = (index: number, row: any) => {
  const pageId = row.postid
  drawerSrc.value = `/#/publish/singlePublish/?id=${pageId}`
  showDrawer.value = true
}
1
2
3
4
5
6
7
8

大功告成。

# 效果预览

​image​

编辑 (opens new window)
#vue#iframe-resize#element-plus#lodash#directive
上次更新: 2024/06/13, 05:26:42
记一次 JavaScript 中的正则转义踩坑

← 记一次 JavaScript 中的正则转义踩坑

最近更新
01
深入剖析MyBatis的架构原理
12-04
02
通用 Mapper 封装
10-09
03
插件源码进一步分析与pageHelper分页插件介绍
10-09
更多文章>
Theme by Vdoing | Copyright © 2011-2024 Terwer Green | MIT License | 粤ICP备2022020721号-1 | 百度统计
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式