bounty将在6天内到期。此问题的答案有资格获得+50声望奖励。baitendbidz正在寻找一个规范答案。
我使用的是Vuetify text-fields,如果内容大于字段宽度(用户需要滚动),我希望显示包含内容的工具提示。工具提示应该只在悬停时出现(默认行为)。我从以下内容开始
(Playground)
<script setup lang="ts">
import { ref, computed } from "vue";
const currentValue = ref("");
const textFieldComponent = ref<VTextField>();
const isTextFieldCuttingOffContent = computed(() => {
if (!textFieldComponent.value) {
return false;
}
if (!currentValue.value) {
return false;
}
return (
textFieldComponent.value.$el.clientWidth <
textFieldComponent.value.$el.scrollWidth
);
});
</script>
<template>
<v-container style="width: 300px">
<v-tooltip :text="currentValue" :disabled="!isTextFieldCuttingOffContent">
<template v-slot:activator="{ props }">
<div v-bind="props">
<v-text-field
ref="textFieldComponent"
label="label goes here"
v-model="currentValue"
/>
</div>
</template>
</v-tooltip>
</v-container>
</template>
我还尝试使用一个观察者而不是计算 prop (Playground)
问题是isTextFieldCuttingOffContent
总是返回false,因为clientWidth
和scrollWidth
总是相等的。你知道哪里出问题了吗?
3条答案
按热度按时间slsn1g291#
1.)
watch()
变量,使用nextTick()
scrollWidth
由于DOM操作而发生更改。如果console.log输入字段的当前scrollWidth
,它确实会在代码中正确更改。然而,这里的问题是这些DOM数据在VueReact性系统中不会自动更新。要检索更新后的值,可以使用
nextTick()
。但是,等待nextTick()
的值以确保DOM操作完成是很重要的。因此,您应该在async函数中调用它。使用computed()
通常不适合此目的。相反,最好只在感兴趣的值发生变化时检查scrollWidth
是否发生了变化。要实现这一点,可以使用
watch()
函数。您可以指定要观察哪个变量的更改,以及在检测到更改时执行哪个函数。在本例中,我们将监视currentValue
变量并执行一个异步函数。因此,当currentValue
更改时,将执行async函数,等待使用nextTick()
的更新,然后检查新的clientWidth
和scrollWidth
之间的差异。然后,true/false值存储在一个单独的变量中,该变量可以在代码中引用。示例
升级(2023-06-19 #1)(灵感来自@tao的评论)
2.)
watch()
变量,使用Observer
如果您不仅需要在输入时检查
scrollWidth
与clientWidth
,而且还需要在任何宽度操作(例如调整大小或其他更改)期间检查,那么请随时实现@tao提到的Observer解决方案!然而,需要注意的是,我的解决方案在这种情况下仍然是必不可少的,因为它主要关注在键入过程中观察scrollWidth
的变化,而Observer无法直接跟踪这些变化,因为它主要监视DOM操作和/或元素大小调整,当键入输入字段或使用JavaScript修改变量时不会触发这些操作。**要了解观察员如何工作,请阅读@tao的信息性回答。
示例
摘要
**监控变量是必要的,在任何情况下都是不可避免的。**此外,通过@tao提到的功能,您还可以考虑意外事件,例如调整浏览器窗口大小,以确保工具提示显示按预期工作。这取决于具体的情况和要求,您是否需要监视变量之外的任何东西。
我已经准备了一个示例代码片段用于演示目的,以便您可以比较代码和结果。
在Vue SFC Playground上尝试解决方案
qojgxg4l2#
@rozsazoltan的答案*1***(将
.scrollWidth
和.clientWidth
之间的差异 Package 到nextTick()
中,等待DOM更新)是一个快速解决方案,将涵盖大多数情况。很有可能,这正是您在当前情况下所需要的。但是,既然你要求一个规范的答案(这意味着你想要在所有**可能的情况下都有效的东西),这个解决方案是不够的,因为它假设元素的
.clientWidth
和.scrollWidth
只在文本内容改变时改变,这是不正确的。它们也可以在以下情况下更改:
window
对象)或其后续兄弟的大小font-size
、font-family
、white-space
、word-wrap
等)为了捕捉(并响应)所有这些变化,您需要:
.scrollWidth
和.clientWidth
值的函数,将它们置于组件状态的某个位置。通过这种设置,两者之间的差异将是无功的,而不需要nextTick()
。它将涵盖所有案件。概念证明(伪代码):
如果您需要一个实际的实现示例,请告诉我,我将从您的沙箱开始创建一个。
1-当时我回答rozsazolnan的答案还没有包含resize和mutation观察器,这是我添加我的观察器的主要原因(也是为了展示稍微不同的语法)。现在佐尔坦的答案是完整的。
rjee0c153#
检查clientWidth和scrollWidth属性可能是您的问题。时间可能是罪魁祸首-特别是当你试图访问它们的时候。元素的最终尺寸可能尚未建立,或者渲染过程可能尚未完成。
当currentValue发生变化时,通过不断检查尺寸,结合React式监视器可以确保精确的测量。为了实现这种技术,这里是代码的修订版本。
每当currentValue的值发生变化时,就会调用checkTextOverflow函数,以确保在DOM更新之后获取clientWidth和scrollWidth的测量值。
使用React式监视器修改isTextFieldCuttingOffContent变量可以精确地识别文本字段何时截断内容。:)希望这有帮助!