Vuetify v-text-field溢出动画实现问题求助
解决Vuetify v-text-field溢出滚动动画问题
问题分析
原方案的核心痛点:
- 手动固定
input宽度无法适配动态输入内容 - 父容器设
overflow:hidden后,固定百分比的translate动画无法匹配实际溢出宽度,导致动画失效或滚动位置偏差
解决方案
通过CSS变量+JS动态计算偏移量结合,实现自适应内容的滚动动画,同时保持父容器overflow:hidden完成溢出裁剪:
<script setup> import { ref, watch, nextTick } from 'vue' const text = ref('very long long long long long text') const inputRef = ref(null) // 监听文本变化,更新滚动偏移量的CSS变量 watch(text, async () => { await nextTick() if (!inputRef.value) return const { scrollWidth, clientWidth } = inputRef.value // 计算需要滚动的总距离:内容总宽度减去容器可见宽度 const scrollOffset = scrollWidth - clientWidth inputRef.value.style.setProperty('--scroll-offset', `-${scrollOffset}px`) }) // 初始化时计算一次偏移量 nextTick(() => { if (inputRef.value) { const { scrollWidth, clientWidth } = inputRef.value const scrollOffset = scrollWidth - clientWidth inputRef.value.style.setProperty('--scroll-offset', `-${scrollOffset}px`) } }) </script> <template> <div class="container"> <v-text-field v-model="text"> <template v-slot:input="{ props }"> <input v-bind="props" ref="inputRef" class="animated-input" /> </template> </v-text-field> </div> </template> <style> .container { width: 200px; } /* 父容器固定宽度+溢出隐藏,裁剪超出内容 */ .v-field__input { overflow: hidden; width: 100%; } /* 输入框自适应内容宽度,禁止换行 */ .animated-input { width: auto; white-space: nowrap; animation: scrollText 3s infinite alternate ease-in-out; } @keyframes scrollText { 0%, 20% { transform: translateX(0); } 80%, 100% { /* 使用动态计算的CSS变量作为滚动终点 */ transform: translateX(var(--scroll-offset, 0)); } } </style>
关键实现细节
- 自适应宽度:给
input设置width: auto+white-space: nowrap,让输入框自动匹配文本长度 - 动态偏移计算:通过
scrollWidth(内容总宽度)和clientWidth(容器可见宽度)的差值,得到实际需要滚动的距离,用CSS变量传入动画 - 溢出裁剪:父容器
.v-field__input保持overflow:hidden,确保超出部分被裁剪,同时不干扰动画执行 - Vuetify插槽复用:通过
input插槽直接获取原生input元素的引用,方便DOM操作
额外优化建议
- 添加判断逻辑:当文本未超出容器宽度时,自动暂停动画,避免无意义滚动
- 调整动画的缓动曲线及时长,让滚动效果更自然流畅
内容的提问来源于stack exchange,提问作者jonen
相关产品推荐
相关产品推荐

