背景
第一个需求
不管是在移动端还是 pc 端,都有一些需要缓存数据的场景。
比如,在一个数据展示页,这是一个 tableList,当用户点击某一行数据,就会进入这条数据的详情页。当用户返回数据展示页的时候,我们希望能帮助用户留住之前的页面状态,诸如:已经输入的筛选条件、当前 table 跳转的页数 等。
在以前 jQuery 的时代,我们有几个办法来做
在全局添加缓存,将数据缓存起来
把各种需要缓存的数据拼接在 url 上
放到本地存储中
这几个办法其实是疏通同归,需要在用户返回数据展示页的时候重新渲染页面的状态。
对于 vue 而言,当然有更好的姿势来满足这个需求。 vue 提供了内置组件 keep-alive 来帮我们做这个事情。
当我们需要缓存一个 table 的时候,只需要:
<transition><keep-alive><component:is="view"></component></keep-alive></transition>
是不是超级简单呢?
第二个需求
现在,这个 table 中有些数据很长,一个表格是装不下的。比如这一段携带参数的 url :https://www.baidu.com/link?url=tsptvz-cU2m2HFPFwje315C6Y8BLh0nPi5xD8t-RL5S&wd=&eqid=d4c41bfd00026e520000000360af7907
那我们想要这个 url 在 table 里完全展示出来是不现实的。
所以很多 ui 框架,都提供了一个功能,叫做show-overflow-tooltip
,比如基于 vue 的 elementui 提供了 show-overflow-tooltip 这样一个属性,当表格中内容过长被隐藏时显示 tooltip。
这么一看,前端还挺简单的哈,站在巨人的肩膀上,果然一览众山小。
问题
然后,有一天测试的小姐姐就提了一个 bug,她说当她从数据展示页面进入详情页的时候,tooltip 不消失,在那里明晃晃的。
纳尼?!开启测试环境看一下,又是哪个刁民想害朕。
回想了问题出现的时间节点和 git 提交的注释,居然是在我加上了 keep-alive
之后。
然后我测试了一下,同时使用 keep-alive 和 show-overflow-tooltip 就会出现这个问题。去项目的 github 上搜一下,原来不是我一个人
虽然问题搜到了,但是后面没跟着解决办法,唉
分析
show-overflow-tooltip 实际会生成一个 tooltip 提示框,加载到 body 下。
当组件被销毁时,其 display
属性被赋值为 none
,从而实现隐藏效果。
当我们代码中使用 keep-alive
将组件缓存起来,即便路由已经跳转,但由于组件不会销毁,tooltip 提示框则不会自动隐藏。
在我翻阅了 github、stackoverflow、google 之后,我没有找到有效的解决办法,气急败坏的我决定使用最简单粗暴的办法
解决
我决定直接使用 js 将这个恼人的 tooltip 隐藏掉。
包裹在 keep-alive
组件中的的组件在被切换时会调用 activated
、deactivated
两个生命周期的钩子方法。
其中 activated
是缓存组件激活时调用的,而 deactivated
是路由跳转到其他组件时调用的
所以,代码可以这样写:
import{Vue,Component}from'vue-property-decorator'constforEach=function(array,callback,scope){for(leti=0;i<array.length;i++){callback.call(scope,i,array[i])}}@ComponentexportdefaultclassMyComponentextendsVue{deactivated(){constmyNodeList=document.querySelectorAll('.el-tooltip__popper')forEach(myNodeList,function(index,value){value.style.display='none'},null)}}
这段代码的意思是,在路由即将离开的时候,查找所有的 el-tooltip__popper 并将其 display
属性设置为 none
。
哈哈哈,是不是既简单又粗暴。
改完以后,在 jira 上更改 bug 的状态为已修复,顺便留言请测试的小姐姐吃个晚饭
测试虐我千百遍, 我待测试如初恋, 每一次亲手写出的 bug , 都是为烛光晚餐埋下的伏笔~
作者:晴天同学