news 2026/9/12 2:07:56

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
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>
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/10 21:12:42

IMU和GPS ekf融合定位 从matlab到c++代码实现 基于位姿状态方程

IMU和GPS ekf融合定位 从matlab到c代码实现 基于位姿状态方程&#xff0c;松耦合 文档且详细 蹲在实验室捯饬了三天咖啡机之后&#xff0c;我终于把IMU和GPS的EKF融合算法从Matlab搬到了C。这事儿就像把乐高积木从说明书模式切换到自由创作模式——你知道原理是对的&#xff0…

作者头像 李华
网站建设 2026/9/11 18:03:29

无人值守地区的可靠选择 的远程监测能力

对于环境恶劣的高山、海岛、边境、自然保护区等无人值守的边远地区&#xff0c;建立自动气象站面临供电难、维护难、环境苛刻度高等多重挑战。FST200-207抗冰冻型超声波风速风向传感器的低功耗、高可靠和易集成的特点&#xff0c;使其成为此类应用的理想解决方案。 超声波风速…

作者头像 李华
网站建设 2026/9/12 1:41:47

linux部署分布式redis集群保姆级教程

一、Redis常用的三种集群模式主从&#xff08;单体架构项目&#xff09;通过持久化功能&#xff0c;Redis保证了即使在服务器重启的情况下也不会丢失&#xff08;或少量丢失&#xff09;数据&#xff0c;因为持久化会把内存中数据保存到硬盘上&#xff0c;重启会从硬盘上加载数…

作者头像 李华
网站建设 2026/9/11 20:23:08

鸿蒙开发者的价值跃迁:把经验变成“智能资产”,让AI为你赋能

在鸿蒙生态加速扩张的当下&#xff0c;开发者之间的竞争早已不再是“会不会用技术”的较量&#xff0c;而是“能不能让经验产生持续价值”的比拼。近期&#xff0c;一场鸿蒙开发者闭门交流会中的真实案例&#xff0c;深刻揭示了这一核心趋势。某互联网公司承接了智慧医疗领域的…

作者头像 李华
网站建设 2026/9/11 12:07:14

【注意】非量表问卷不需要做信效度分析!量表问卷信效度检验指标详解

不少人在做研究时可能会遇到这样的场景&#xff1a;明明按照教程一步步把问卷数据做了信效度检验&#xff0c;却被一句“这些分析不能做”打回重来。很多人这才意识到——原来信效度分析并不是所有问卷的“必做项目”。 一、非量表问卷vs量表问卷 在实际研究中&#xff0c;问…

作者头像 李华
网站建设 2026/9/11 11:17:14

PHOTO1111

作者头像 李华