购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

2.5 条件渲染指令

在实际项目开发中,有两种场景非常常见:第1种是局部页面需要在满足某种条件后显示;第2种是在多个不同的页面效果之间进行切换显示。无论哪一种场景,都只有在满足某种条件后才能渲染显示。在Vue中将其称为条件渲染,可以通过v-if相关指令或v-show指令实现。

2.5.1 v-if相关指令

v-if指令用于控制元素的显示或者隐藏,其相关指令包含v-if、v-else和v-else-if。v-if与v-else-if指令的表达式类型需要是布尔类型,当结果为true时,也就是满足条件后,才显示对应的元素;v-else指令不需要指定表达式,只需要指定属性名,当元素前面的v-if和v-else-if指令都不满足条件时才会显示。

如果只有一个页面的条件渲染,则推荐使用v-if指令来渲染;如果有两个页面的条件渲染,则推荐配合使用v-if与v-else指令来渲染;如果超过两个页面的条件渲染,则推荐配合使用v-if、v-else-if和v-else指令来渲染。

先阅读下方代码并思考其运行效果,然后在下方代码的基础上进行优化。

这段代码比较简单,页面上会显示data方法中score的值和一个按钮,当点击按钮后,score的值增加10。初始页面效果如图2-27所示,点击按钮后的页面效果如图2-28所示。

图2-27 初始页面效果

图2-28 点击按钮后的页面效果

现在的需求是:只有当入学测试得分小于60分的时候元素才会显示。

此时我们就可以通过v-if指令来实现。在button按钮上做简单改动,具体如下。

当v-if指定的表达式的值为true时,元素才会显示。对于上方代码来说,初始时score的值为55,按钮被显示,点击按钮后,因为score的值大于60,所以按钮自动消失了。

现在添加一个新需求:当入学测试得分大于或等于60分时,显示绿色的h3文本提示;当入学测试得分小于60分时,显示红色的h4文本提示。文本提示如图2-29所示。

图2-29 文本提示(1)

根据前面的学习,读者可能想到了使用v-if指令对h3和h4标签进行控制,但实际上,Vue提供了更便捷的方式,前面提到过v-if的相关指令,对于这个需求就可以配合使用v-if和v-else实现。不过需要注意的是,v-else指令不需要指定表达式。

此时Vue代码变为下方代码。

v-if指令的页面效果与上一段代码的页面效果相同,这里不做过多讲解,但当不满足v-if指令的条件时,就会显示v-else指令所在的元素。此时data方法中的score值为55,不满足条件,只会显示“很遗憾,你的面试没有通过……”。

用户的需求总是多变的。现在需求再次更改:当入学测试得分大于或等于60分时,显示绿色的h2文本提示;当入学测试得分小于50分时,显示红色的h3文本提示;当入学测试得分在50~60分(包括50分)时,显示黄色的h4文本提示。文本提示如图2-30所示。

图2-30 文本提示(2)

此时可以配合使用v-if、v-else-if和v-else指令来实现。需要注意的是,只有当v-else-if指令指定的表达式的值为true时,对应的标签才会显示。

Vue代码变为下方代码。

当score的值大于或等于60时,显示“欢迎来尚硅谷学习!”;当score的值在50~60(包括50)时,会显示“此次测试没有完全通过,可选择复试。”;其余情况则显示“很遗憾,你的入学测试没有通过,可以考虑UI或测试。”。

前面都是对一个标签进行条件渲染,那么如果有多个标签要怎么处理呢?

我们可以用template标签来包含要实现条件渲染的多个标签,并在template标签上使用v-if指令来判断元素是否显示。需要注意的是,template标签只在模板中存在,并不会产生任何HTML标签,具体如下。

运行代码后,因为score的值初始为55,不满足v-if指令的条件,所以只显示入学测试得分和“学习后再复试一次”按钮。当点击“学习后再复试一次”按钮后,score的值更改为65,满足v-if指令的条件,显示其余3个按钮。

此时我们观察页面结构,发现没有template标签,验证了“template标签只在模板中存在,并不会产生任何HTML标签”的说法,如图2-31所示。

图2-31 页面结构

2.5.2 v-show指令

在Vue中,v-show指令也可以实现条件渲染。当v-show指令指定的表达式的值为true时,对应的标签才会显示。

下面我们将v-if指令中涉及的案例使用v-show指令来实现。

代码片段1如下。

当score的值小于60时,显示“学习后再复试一次”按钮。

代码片段2如下。

当score的值大于或等于60时,显示“欢迎来尚硅谷学习!”;当score的值小于60时,显示“很遗憾,你的入学测试没有通过……”。

代码片段3如下。

当score的值大于或等于60时,显示“欢迎来尚硅谷学习!”;当score的值在50~60(包括50分)时,会显示“此次测试没有完全通过,可选择复试。”;其余情况则显示“很遗憾,你的入学测试没有通过,可以考虑UI或测试。”。

因为初始score的值是55,所以当点击按钮时,文本提示会切换显示,按钮也会被隐藏。需要注意的是,v-show指令是不能与v-else和v-else-if指令配合使用的。当需要在多个标签之间切换显示时,要使用多个v-show指令来实现。还有一点要特别注意,v-show指令不能用在template标签上。

2.5.3 比较v-if和v-show指令

通过前面的学习我们得知,v-if和v-show指令实现的功能是一致的,但实际上,二者内部的实现机制截然不同,这一点是在理论面试时经常被提问的问题。

在初始化解析显示时,如果表达式的值为true,那么二者的内部处理相同;如果表达式的值为false,则内部处理完全不同。v-if指令对应的模板标签结构不会被解析,也就不会产生对应的HTML标签结构;而v-show指令则会解析模板标签结构,生成HTML标签结构,只不过它会通过指定display为none的样式来隐藏标签结构。

在更新数据后,表达式的值变为true,需要显示标签结构。v-if指令的标签会新建HTML标签结构并显示,而v-show指令只需要去除display为none的样式让标签结构重新显示出来。

当再次更新数据后,表达式的值变为false,需要隐藏标签结构。v-if指令的标签直接被删除,内存中v-show指令不再有对应的DOM结构;v-show指令的标签通过指定display为none的样式来隐藏标签结构。

通过下方代码进行验证。

Vue代码如下。

JavaScript代码如下。

在上方代码中,通过v-if指令控制h1标题的显示/隐藏,通过v-show指令控制h2标题的显示/隐藏。

在初始显示时,由于isShow的值为false,因此h1与h2两个标题都不可见。通过查看页面结构可以发现h1标题不存在,但h2标题是存在的,只是通过指定display为none的样式来隐藏标签结构,如图2-32所示。

点击“切换标识”按钮对isShow标识进行取反,isShow的值更新为true。此时h1和h2两个标题都会显示,但通过v-if指定控制的h1标题是新创建的,而h2标题是通过删除display为none的样式显示出来的,如图2-33所示。

图2-32 查看页面结构(1)

图2-33 查看页面结构(2)

当再次点击“切换标识”按钮时,isShow的值更新为false。此时h1标题和h2标题都会消失,但v-if指令控制的h1标题被删除,而通过v-show指令控制的h2标题存在,只是添加了display为none的样式。

最后简单总结一下v-if与v-show指令的区别,在隐藏时,v-if指令会删除标签,而v-show指令只是通过样式控制标签不显示;当再次显示时,v-if指令需要重新创建标签,而v-show指令只需要更新一下样式就可以显示。

对于使用场景的选择,如果条件渲染的条件变化相对频繁或要控制的标签结构比较大,那么选择v-show指令比较合适。因为v-if指令在从隐藏变为显示时,需要重新创建DOM结构,效率相对低一些,但v-show指令在隐藏时,标签结构没有被删除,比v-if指令占用的内存更大一些。这也就是编程世界中经常说到的:“以空间换时间的技术”,即用更大的占用空间,换取后面更少的执行时间。

还有一点需要注意的是,如果初始渲染条件的值为false,则v-if指令是不会解析模板产生HTML标签的,有时也称它为懒加载,但v-show指令不是懒加载。 PbT19k0MowTjs44IrAIKKYkYjXiT2BGVML9jVlQTGhYjldRvDncbdLHviE272r1P

点击中间区域
呼出菜单
上一章
目录
下一章
×