当前位置: 首页 > news >正文

Vue3利用ResizeObserver监听Textarea的尺寸动态调整表格tbody的maxHeight

调整表格tbody的maxHeight推荐方式是直接修改css,本文主要描述的是不推荐但使用ResizeObserver再进一步修改dom的maxHeight(之所以选择ResizeObserver这个API是因为Textarea默认没有resize事件),从而达到不溢出可视窗口,表格内容区域自适应并纵向滚动

一、直接修改行内样式

<template> <div ref="contentRef"> <my-content class="content"> <top-info class="top-info" v-model:loading="topLoading" v-model:isEdit="isEdit" /> <my-list /> </my-content> </div> </template> <script lang="ts" setup> import { CSSProperties } from 'vue'; import { nextTick, watch, onUnmounted } from 'vue'; import { debounce } from 'lodash-es'; import MyList from './MyList.vue'; import TopInfo from './TopInfo.vue'; const contentRef = ref(); const topLoading = ref(false); const isEdit = ref(false); const getContentDom = () => contentRef.value.querySelector('.content'); const getTbodyDom = () => getContentDom().querySelector('.my-table-body'); const getTopDom = () => getContentDom().querySelector('.top-info'); const getTopTextarea = () => getTopDom().querySelector('textarea'); const handleTableMaxHeight = debounce(() => { const contentDom = getContentDom(); const tbodyDom = getTbodyDom(); if (tbodyDom) { const topDom = getTopDom(); const tableMaxHeight1 = contentDom.clientHeight - topDom.scrollHeight - 180; // 为了展示逻辑下方直接修改样式,可以传值,有的table插件有maxHeight参数有此类效果,如果maxHeight参数没有响应式效果再考虑直接操作dom样式 tbodyDom.style.maxHeight = tableMaxHeight1 + 'px'; tbodyDom.style.overflowY = 'auto'; } }, 200); const watchTextarea = debounce(() => { const textarea = getTopTextarea(); const resizeObserver = new ResizeObserver((entries) => { for (let entry of entries) { const { width, height } = entry.contentRect; console.log('New dimensions:', width, height); // 处理尺寸变化,例如更新数据或执行其他操作 } nextTick(() => { handleTableMaxHeight(); }); }); resizeObserver.observe(textarea); textarea.__resizeObserver__ = resizeObserver; // 保存引用以便之后可以访问或清理(可选) }, 200); onUnmounted(() => { const textarea = getTopTextarea(); if (textarea.__resizeObserver__) { textarea.__resizeObserver__.disconnect(); } }); watch( () => [isEdit.value, topLoading.value], () => { nextTick(() => { handleTableMaxHeight(); const textarea = getTopTextarea(); if (textarea) { watchTextarea(); } }); }, { deep: true, immediate: true } ); </script>

二、利用组件style对象传参修改css的important样式

比style行内样式优先级高的是css的important样式,使用scss或者less的var函数,可以传递获取tbody的maxHeight

<template> <div ref="contentRef"> <my-content class="content"> <top-info class="top-info" v-model:loading="topLoading" v-model:isEdit="isEdit" /> <my-list :style="tbodyStyle"/> </my-content> </div> </template> <script lang="ts" setup> import { CSSProperties } from 'vue'; import { nextTick, watch, onUnmounted } from 'vue'; import { debounce } from 'lodash-es'; import MyList from './MyList.vue'; import TopInfo from './TopInfo.vue'; const contentRef = ref(); const topLoading = ref(false); const isEdit = ref(false); const tbodyStyle = ref<any>({ padding: 0 }); const getContentDom = () => contentRef.value.querySelector('.content'); const getTbodyDom = () => contentRef.value.querySelector('.my-table-body'); const getTopTextarea = () => getTopDom().querySelector('textarea'); const handleTableMaxHeight = debounce(() => { const contentDom = getContentDom(); const topDom = getTopDom(); const tableMaxHeight1 = contentDom.clientHeight - topDom.scrollHeight - 180; tbodyStyle.value['--tbody-max-height'] = tableMaxHeight1 + 'px'; }, 200); const watchTextarea = debounce(() => { const textarea = getTopTextarea(); const resizeObserver = new ResizeObserver((entries) => { for (let entry of entries) { const { width, height } = entry.contentRect; console.log('New dimensions:', width, height); // 处理尺寸变化,例如更新数据或执行其他操作 } nextTick(() => { handleTableMaxHeight(); }); }); resizeObserver.observe(textarea); textarea.__resizeObserver__ = resizeObserver; // 保存引用以便之后可以访问或清理(可选) }, 200); onUnmounted(() => { const textarea = getTopTextarea(); if (textarea.__resizeObserver__) { textarea.__resizeObserver__.disconnect(); } }); watch( () => [isEdit.value, topLoading.value], () => { nextTick(() => { handleTableMaxHeight(); const textarea = getTopTextarea(); if (textarea) { watchTextarea(); } }); }, { deep: true, immediate: true } ); </script> <style lang="less" scoped> :deep(.my-table-body) { max-height: var(--tbody-max-height) !important; overflowY: auto; } </style>
http://www.jsqmd.com/news/106632/

相关文章:

  • 论文文献引用格式最新规范流出,毕业季限时必看!
  • 大模型面试必备03——llama文章精读
  • TikTok多账号风控:找对安全支点,解锁规模化运营
  • 基于大数据的社交网络隐私保护及舆情分析可视化系统课题申报表
  • CUDA初始团队成员锐评cuTile「专打」Triton,Tile范式能否重塑GPU编程生态竞争格局
  • SpringBoot使用设计模式一装饰器模式
  • 基于大数据的热点话题分析系统的设计与实现中期
  • 从零构建AI镜像,缓存命中率提升至95%的3个核心技巧
  • 【往届已检索、ACM出版、见刊检索稳定】第二届数字管理与信息技术国际学术会议 (DMIT 2026)
  • Java 大视界 -- Java 大数据在智能家居能源管理与节能优化中的深度应用
  • 基于大数据的热点话题分析系统的设计与实开题报告 (1)
  • 腾讯云国际站代理商的QAPM服务能提供哪些专属服务?
  • FreeIPA能建立用户组,并将域组带入到加域的客户端
  • 基于java的SpringBoot/SSM+Vue+uniapp的仓储管理系统的详细设计和实现(源码+lw+部署文档+讲解等)
  • 如何解决 pip install 网络报错 ERROR: No matching distribution found for requests
  • 【往届均已成功见刊检索、早鸟优惠】第六届计算机网络安全与软件工程国际学术会议(CNSSE 2026)
  • 200Smart与WinCC通讯
  • 软件测试资源大全:从工具到社区,打造你的职业成长生态
  • 【量子开发效率翻倍秘诀】:深度集成VS Code实现Q#与Python双向代码导航
  • 基于大数据的热点话题分析系统的设计与实开题报告
  • 面向数字孪生系统的全方位测试解决方案
  • 零基础想学黑客技术?整理国内优质网络安全论坛网站,小白入门必备!
  • 为什么90%的团队搞不定云原生Agent部署?Docker批量方案深度拆解
  • Docker Compose Agent配置实战(5个真实场景+完整代码示例)
  • 基于java的SpringBoot/SSM+Vue+uniapp的旅游管理系统的详细设计和实现(源码+lw+部署文档+讲解等)
  • 车载 Android 系统稳定性问题全解析:从性能到黑屏的排查指南
  • 基于大数据的热点话题分析系统的设计与实现文献综述
  • day42 dataset和dataloader
  • 【值得收藏】RAG技术全解析:大模型检索增强生成的挑战、范式与优化策略
  • 部分背包与01背包问题