关于在v-show的使用中遇到的问题—v-show频繁切换后失效
最近在写任务的时候遇到了这样一个问题:
首先,我在 data 中定义有一个 errRanges 数组,这个数组中的数据是来自在页面创建的时候发请求返回的数据,也就是说,每次返回的数据都可能不同。然后,页面上有几个卡片,点击不同的卡片,再次调用相同的接口,但是传的参数不同。
接着,在页面的某一区域,我引用了2个antDesign的组件,一个alert信息警告和一个card卡片,卡片中的description中还用了v-for循环遍历,alert和card这两个组件都使用了v-show来切换显示,具体条件是:当errRanges数组只有一个元素时,显示alert组件;当errRangs数组有多个元素时,显示card组件,部分代码如下:
<div> <a-alert type="info" v-show="errCodeRanges.length == 1"> <div slot="message" class="message"> <span> 错误码范围(十进制):{{ errCodeRanges[0] ? errCodeRanges[0].code_begin : "" }}-{{ errCodeRanges[0] ? errCodeRanges[0].code_end : "" }} </span> <span> 错误码范围(十六进制):{{ errCodeRanges[0] ? errCodeRanges[0].code_begin_hex_string : "" }}-{{ errCodeRanges[0] ? errCodeRanges[0].code_end_hex_string : "" }} </span> </div> </a-alert> <a-card class="errRangepannel" v-show="errCodeRanges.length > 1"> <a-descriptions :column="3"> <a-descriptions-item v-for="(item, index) in errCodeRanges" :label="'错误码范围' + (index + 1)" :key="item.id" > <div class="rangeContent"> <span >(十进制):<a class="c-theme" >{{ item.code_begin }}-{{ item.code_end }}</a ></span > <span >(十六进制):<a class="c-theme" >{{ item.code_begin_hex_string }}-{{ item.code_end_hex_string }}</a ></span > </div> </a-descriptions-item> </a-descriptions> </a-card> </div>
后面点击不同卡片的时候,第一次点击只有一条数据返回的卡片的时候,能够正常显示alert,但是,再次点击返回数据为多条的卡片之后,再点击之前只有一条数据返回的卡片,alert却不显示了
我检查了一遍接口返回的数据,发现返回的数据是对的,但是alert上面绑定的v-show在第二次条件渲染时失效了。
我当时也不知道是什么原因,就想着把alert组件中的v-show换成v-if试试,结果“瞎猫碰上死耗子”,就成功解决了!虽然解决了,但是还是不知道是为什么,所以我就在百度上搜索了一下,找到了一个道友跟我遇到过一个相似的问题,他最后也是通过把 v-show 改成 v-if 之后就解决了问题。这是他的原文:https://www.jb51.net/article/137111.htm。
他最后猜想v-show方法失效的原因大概是因为:
由于el-table-column会生成多行标签元素,根据v-show是不支持template语法的,推断出v-show不能显示隐藏多个元素
但是具体的原因,该道友表示也不清楚,我查了一些资料,觉得应该从根本上去分析v-show失效的原因。这是官方文档中对v-show的描述:
不同的是带有
v-show
的元素始终会被渲染并保留在 DOM 中。v-show
只是简单地切换元素的 CSS propertydisplay
。注意,
v-show
不支持<template>
元素,也不支持v-else
。
再来看看我的布局,在alert组件里面,还放了一个div作为插槽,相当于是通过v-show控制了多个元素的显示与隐藏。然而通过上面引用的官方解释我们可以知道,v-show是不支持这种情况的。于是我把alert组件里的div给注释了,再次运行,发现仍然不行。我就在想是不是因为alert组件它本身就带有插槽,所以不行,于是我换成了span标签来验证猜想,结果如我所料:
重复之前的操作,当再次点击m2时,span标签还在!!!
那么问题又来了,为什么alert组件下面兄弟组件的card的v-show不受影响呢?再来看看card的内部结构:
???难道是因为加了v-for ?于是我把 v-for 去掉了,结果还是没有任何变化,card 的 v-show 丝毫不受影响,怎么切换卡片都还顽强的显示在网页上!这我就十分纳闷了,为什么呢?难道是位置的原因?或者渲染条件的原因?所以接下来我就开始一个一个地尝试猜想:
会不会是位置的原因?
我把alert和card组件在布局上换了一个位置,结果。。。没啥用,猜想错误;
会不会是渲染条件的问题?
我又把alert和card上的v-show中的条件互换了一下,结果。。。仍然没啥用,猜想再次错误。
好吧,以上就当我说了一大堆废话吧,准确的原因我实在猜不出来了哈哈哈哈,还希望大佬们给我指条明路! \>_<\
不过解决办法是没错的,把失效的v-show改成v-if就可以了。跟我一样想要知道原因的小可爱们不要打我哈,写了一大篇总结了一个寂寞,哈哈哈!
等我继续钻研钻研,找到原因了再继续补哈~~~~拜~