news 2026/5/15 18:00:07

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/5/11 3:36:04

FT8440B输出12V350MA,18V300MA 非隔离电源方案 典型应用电路

FT8440B是离线非隔离 Buck 架构、集成 650V 高压启动与功率开关的电流模 PWM 控制器&#xff0c;主打高精度恒压&#xff08;3%&#xff09;、低成本与极简外围&#xff0c;适合 90–264Vac 输入、5–18V 输出、中小功率&#xff08;典型 12V/450mA、18V/300mA&#xff09;的恒…

作者头像 李华
网站建设 2026/5/11 10:20:44

LP3799FBC_48W隔离电源芯片(12V4A)典型应用电路

LP3799FBC&#xff08;TO220-6F&#xff0c;集成≥650V 高压管&#xff0c;原边反馈 PSR 反激&#xff09;适合 48W 级隔离 CV/CC 适配器 / 充电器&#xff0c;外围精简、EMI 友好、待机 < 75mW&#xff0c;量产与安规成本可控。典型应用场景与规格&#xff08;选型速览&…

作者头像 李华
网站建设 2026/5/14 13:49:27

在 Pr 中,3 种高效添加字幕和字幕样式的方法(剪辑师实战分享)

做视频剪辑久了你会发现&#xff0c;字幕本身并不难&#xff0c;难的是做得快、改得稳。 我自己长期用 Adobe Premiere Pro&#xff08;Pr&#xff09; 剪口播、教程和商业视频&#xff0c;踩过很多字幕的坑&#xff1a; 识别慢、断句乱、样式改一次就要返工一堆。 后来逐渐形成…

作者头像 李华
网站建设 2026/5/14 11:35:57

ArrayPool.Shared解说

NET 中频繁创建和销毁数组的情况下会导致垃圾回收器出现严重的内存压力&#xff0c;ArrayPool<T> 通过池化手段有效地降低了数组的分配和垃圾回收器的回收压力&#xff0c;同时 ArrayPool<T> 也是 MemoryPool<T> 和 PipeWriter、PipeReader 的底板。ArrayPoo…

作者头像 李华
网站建设 2026/5/15 14:13:47

VonaJS提供的读写分离,直观,优雅[特殊字符]

在VonaJS中实现读写分离&#xff0c;只需提供一组写数据源和一组读数据源。当用户访问后端 API 时&#xff0c;系统会按照规则自动选择写数据源或读数据源&#xff0c;访问相应的数据库&#xff0c;从而分摊压力&#xff0c;提升系统性能安装模块读写分离作为独立的模块提供&am…

作者头像 李华
网站建设 2026/5/1 9:08:02

鸿蒙6.0:AI与智能体框架(HMAF),重塑操作系统未来的核心密码

当用户说出“帮我规划带老人孩子的周末短途游”&#xff0c;系统便能自动整合行程、餐饮、景点资源生成完整方案&#xff1b;当驾车抵达加油站&#xff0c;车载系统自动识别油枪并完成人脸支付&#xff1b;当需要分析Excel数据&#xff0c;仅凭自然语言就能完成复杂报表生成——…

作者头像 李华