vue3组件通过props传递数据如何拿到更新后的dom的问题?
- 现在有这样一个需求就是一个显示框宽度固定内容超出隐藏并给出提示内容.
解决方案
- 使用
dom的scrollWidth和dom的offsetWidth
通过判断他们之间的大小来进行是否省略隐藏,当然你也可以使用**getBoundingClientRect** api来获取dom的宽度 - 再用**element-plus中的el-tooltip**组件进行封装.
遇到的问题
- 上面的方案是可行的,但问题在于如何动态的去监听dom的宽度来进行动态的省略隐藏,相信列为不比我差,我一开始就想的是在子组件中的updated钩子函数中去操作这个dom,可是事与愿违请看下面一张图片,这张图片的大概意思就是如果你需要在组件更新之后操作dom请使用nextTick().
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WJH08a7z-1660533172473)(C:\Users\NEWARE~1.CN\AppData\Local\Temp\Image.png)]
如何解决
-
问题是找到了但如何解决并且如何合理的使用
nextTick()
,至于nextTick()
的原理只说一个大概.nextTick()
,在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。
-
既然updated中获取不到ref这个实例,我想的是
watch()
这个api一共有三个参数,我重点讲一讲第三个参数-
第三个参数中除了
{deep: true,immediate:true}
这些属性以外还有一个属性就是***flush:'post'
*** 因为要动态的监听数据的宽度是否超出隐藏由于在watch中没法用nextTick()
api.大概是什么意思呢?请看下面 -
<template> <div> <span id="test">测试{{ number }}</span> <el-button size="mini" @click="hanlderClick">flushTest</el-button> </div> </template> <script setup lang="ts"> import { watch, watchEffect, ref } from 'vue' const number = ref(0) const hanlderClick = () => { number.value++ } watchEffect(() => { console.log(number.value, "no flush") console.log(document.querySelector("#test") && document.querySelector("#test")?.innerHTML, "innerHTML") }, {}) </script>
-
-
我们看到vue中是先执行监听器,然后更新dom,第一次为null是因为dom还没有生成.当我点击第一次和第二次的时候这个时候监听器执行完,再获取到上一次的dom内容,最后执行update触发更新.
-
我们加上
flush:'post'
之后再执行看看 -
总结
-
-
最后如果我们需要再watch中数据更新之后获取到最新的dom的时候可以添加一个
flush: 'post'
这个属性获取.
-
总结
主要是通过再watch中监听数据的变化拿到dom的变化最后做出实时的响应变化.
世上无难事,只要你肯放弃,加油.