Javascript 如何在Vue中检测组件内的元素是否溢出?
我有一个组件Javascript 如何在Vue中检测组件内的元素是否溢出?,javascript,vue.js,dom,vue-component,overflow,Javascript,Vue.js,Dom,Vue Component,Overflow,我有一个组件ResultPill,带有主容器的工具提示(已实现)。工具提示文本由getter函数tooltip(我使用vue属性装饰器)计算,因此相关位为: <template> <div class="pill" v-vk-tooltip="{ title: tooltip, duration: 0, cls: 'some-custom-class uk-active' }" ref="container" >
ResultPill
,带有主容器的工具提示(已实现)。工具提示文本由getter函数tooltip
(我使用vue属性装饰器)计算,因此相关位为:
<template>
<div class="pill"
v-vk-tooltip="{ title: tooltip, duration: 0, cls: 'some-custom-class uk-active' }"
ref="container"
>
..some content goes here..
</div>
</template>
<script lang="ts">
@Component({ props: ... })
export default class ResultPill extends Vue {
...
get tooltip (): string { ..calcing tooltip here.. }
isContainerSqueezed (): boolean {
const container = this.$refs.container as HTMLElement | undefined;
if(!container) return false;
return container.scrollWidth != container.clientWidth;
}
...
</script>
<style lang="stylus" scoped>
.pill
white-space pre
overflow hidden
text-overflow ellipsis
...
</style>
我发现对于我的组件的许多实例,$refs.container
是未定义的
,因此isContainerSqueezed
实际上没有帮助。我是否必须为每个组件实例设置唯一的ref
?这种方法还有其他问题吗?如何检查元素是否溢出
PS为了检查引用的非唯一性是否会影响案例,我尝试将以下内容添加到class a random id属性中:
containerId = 'ref' + Math.random();
然后像这样使用它:
:ref="containerId"
>
....
const container = this.$refs[this.containerId] as HTMLElement | undefined;
但它没有帮助:工具提示仍然没有改变
更好的是,还有$el
属性,我可以用它来代替refs,但这仍然没有帮助。看起来原因是:
关于ref注册计时的一个重要注意事项:由于ref本身是作为render函数的结果创建的,因此您无法在初始渲染时访问它们-它们还不存在$refs
也是非反应性的,因此不应尝试在模板中使用它进行数据绑定
(大概同样的情况也适用于
$el
),所以我不得不在挂载时重新添加工具提示。看起来像我需要的,但答案不适用于我的情况。因此,正如我在其中一次编辑中提到的,文档警告说,$refs
不应用于初始渲染,因为当时没有定义它们。因此,我将tooltip
作为一个属性而不是getter,并在mounted
中计算它:
export default class ResultPill extends Vue {
...
tooltip = '';
calcTooltip () {
// specific logic here is not important, the important bit is this.isContainerSqueezed()
// works correctly at this point
this.tooltip = !this.isContainerSqueezed() ? this.mainTooltip :
this.label + (this.mainTooltip ? '\n\n' + this.mainTooltip : '');
}
get mainTooltip (): string { ..previously used calculation.. }
...
mounted () {
this.calcTooltip()
}
}
也许是打字稿的外壳?尝试直接调试此.$refs.container
,除非您在装载之前设法调用该函数,否则应该始终定义它。@这是极不可能的,因为TS在生产中被剥离,所以isContainerSqueezed
实际上只包含const container=this.$refs.container
和比较。可能会影响这个案例的是整个decorator内容(它可能在没有TS的情况下使用)、vue中getter结果的一些“智能缓存”(DOM引用不可见,是吗?)或者对唯一引用的需要(不过我尝试将其切换为随机引用,但它不起作用;我将相应地更新这个问题)听起来仍然像是通话顺序的问题。尝试在this.$nextTick(()=>{})中包装函数调用代码>。在您的代码示例中,我看不出您在何时何地实际调用了isContainerSqueezed()
函数。@Flame确实是(在上一次编辑中显示了isContainerSqueezed
的用法;我使其更加详细和明显)。我最终使用了挂载的
而不是$nexTIck
,我将发布我目前使用的解决方案
export default class ResultPill extends Vue {
...
tooltip = '';
calcTooltip () {
// specific logic here is not important, the important bit is this.isContainerSqueezed()
// works correctly at this point
this.tooltip = !this.isContainerSqueezed() ? this.mainTooltip :
this.label + (this.mainTooltip ? '\n\n' + this.mainTooltip : '');
}
get mainTooltip (): string { ..previously used calculation.. }
...
mounted () {
this.calcTooltip()
}
}