eltable浮动列里refs失效

这是一个小伙伴投稿给我的前端bug

它用的是vue和elementUI哈

然后他的问题就是

在他的页面上引用了一个子组件

然后通过ref找到这个子组件

调他的一个方法

但是不起作用

来看一下啊

我把这个跑起来就是这样

首先呢这是一个表格

然后最右边这一列操作

它是一个可浮动的

大家看

点击这一个呢

它就会弹出一个popper

里边这就是一个子组件

大家看它的问题就是

这个子组件的数据没出来

但是呢大家看啊

这个输出已经有了

数据已添加

看到源代码在这里

它这个是调的子组件的init()的方法

然后呢子组件

在这里

“数据已添加”

把数据都赋上了

然后刚开始我看这个问题

好像还挺简单

因为它是在循环里嘛

就在表格里每一行都有一个这个组件

所以它上面这样写ref肯定是不行的

因为它有很多个这个Demo组件

所以呢我就以为把这改好就可以了

大家看就这样

正好它上面不是有这个索引吗

我们就把这个行号这个索引拿过来

好正好他这个方法里

也把这个行号传进去了

那然后我们在这用的时候也拼接一个

我以为就OK了

我们来试一下啊

大家看还是不行

所以就很奇怪

然后呢我就想去看看

这个子组加了init()的方法嘛

我一看他这块是个数组

我就想会不会是因为数组的原因

导致这个vue没有

监听到他的变化嘛

然后就简单一点

把它换成一个

把它上面再放一个简单的一个变量

比如ABC吧

(ABCD)然后放这儿

我们默认比如说default

然后呢我们在init()下边儿

我们把这个this.abcd等于123吧

大家看!它还是default

这个123就没过来

就到这我就越来越觉得

好像这个bug不太一般哈

我就想能不能把这个popper拿出来

再试一下

就不放在表格里

直接把这块拿过来哈

然后呢把它叫做Demo

大家看啊

我把这控制台先清空一下

哎大家看这个就好使

而且这个变成123了

所以就很奇怪

只要放到table里就不行

然后后来呢

我就想:那要不然我就把它改成

因为他现在trigger是click嘛

我就把它改成手动的

然后呢绑定一个v-model

正好他v-model下不是用这个isShow嘛

就拿它当v-model

正好他下边这个方法里

也在控制这个isShow

所以我们就拿它做测试啊

但没想到有意外收获啊

我们看一下

注意看啊

我点一下

大家看了吗

后边还有一个

就是他弹出来两个popper

我把这个页面缩小一下哈

大家看一

个指向这个操作

这一列另一个指向了这个地方

所以到这我一下就想起来

因为他这个项目里用了这个

fix的这一列就是这一列是浮动的

在这里

所以el-table

为了实现这种浮动的这一列的功能

哈它就复制了一列,(然后)隐藏(原来)的

就原来这是一列

它就会复制一列放在最右边

然后把原来那个隐藏掉

而我们通过REF找到的那个组件

其实是被隐藏起来的那一个

所以我们调的init的方法

其实是把被隐藏起来的那个组件

加载正确了

然后真正显示的页面上的这个组件

它没有被init的

所以呢就没有数据

我们可以试一下啊

我们把这个fixed去掉

大家看!刷新一下

大家看,这就没有问题了

我们把把它改成click

然后把这个v-model去掉

刷新一下

大家看,这就没有问题了

只要我们把它这个加上fixed

把这个去掉

这还有click

它就会出现刚才那种bug

看看所以正常来说

我觉得这应该属于elementUI的一个bug

也就是说如果我们用了这种浮动的列

然后里边呢

又有又用了这个REF

那我们在尝试用这REF取的时候

应该是取到真正显示的这个REF

这样就没有问题了

那回到项目里

我们应该怎么解决这个问题呢

其实就是去修正这个

this.$refs 的里边的值

因为这种bug不光是Popper组件

其实所有的组件只要放到fix里边

它可能都会出现这种情况

所以呢我们尽量公用一点

所以呢我就想到我们用自定义指令

我们先在main.js里边登记一个指令

就在这里边

我们单独新创建了一个文件

我们打开这文件

在这里前面是一个公用方法

主要在下面export default

然后呢指令名叫这个fixed-column-ref

就相当于未来

我们怎么使用呢

我们在页面上哈

未来只要是这种

在fix的这种column里边

需要用到这个REF的地方

我们再把这个指令加上

这样就可以了

然后具体应该怎么写呢

大家看我们首先呢找到这refName

这种方法是找到这个组件的refName

如果它没有refName呢

我们就不用执行这个自定义的组件(指令)了

好然后呢

我们在这块就是去判断

他这个组件是不是在最右边这一列

就fixed这一列里边

如果是的话

大家看就这个变量

如果是

那么我们就把这个组件的实例在这

这是这个组件的实例

我们把它备份到一个当前页面

这个vnote.context就是整个这个页面

把它放到一个我们自己起一个名字

放到一个备份的属性里边

相当于我们自己创建了一个REF

然后把这个实例放进去先

然后等下一次被隐藏的列执行的时候

走到else

相当于他不在这个最右侧这一列

那我们就把之前备份的取出来

放到真正的这个REF里面

就放回去

这样的话修正它错误的REFS就可以了

然后具体怎么去判断它是不是

在fixed这一列呢

其实也就是一层一层往上找

找到el-table(组件)

看它样式是不是这种哈

所以具体的我就不给大家演示了

然后使用起来的话呢

就是这个效果了

好我们试试哈

啊这块指定一个加:v-

我们再试试

刷新一下,大家看!

这样就可以了

把它也删掉

最后更新于

这有帮助吗?