第九节:Vue指令:v-if条件判断

1.v-if指令

v-if指令是用来控制元素的切换显示


1.1 条件判断指令的基本使用
1.1.1 v-if 指令的基本使用
<!-- HTML --->
<div id="app">
    <h2 v-if="seen">你现在能看到我</h2>
</div>

<!-- JS --->
<script>
    const vm = new Vue({
        el: "#app",
        data: {
            seen:true
        }
    })
</script>

示例说明:

  1. 如果在控制台输入 vm.seen = false,你会发现之前显示的消息消失了。
  2. 因为v-if指令会根据seen的布尔值来判断当前h2需不需要显示
  3. 如果是其他数据类型会转为布尔值

1.1.2 v-else

看到这个是不是很熟悉,在JavaScript中,if流程控制语句中会有一个else,当条件为假的时候执行,.

那么既然在vue中有v-if指令来做添加判断,可定会有一个指令v-else来配合v-if条件为假的时候显示

示例: 使用 v-else 指令来表示 v-if 的“else 块”:

<div v-if="Math.random() > 0.5">
  你能看到我
</div>
<div v-else>
   你看不到我
</div>

注意事项:

  1. v-else 元素必须紧跟在带 v-if 或者 v-else-if 的元素的后面,否则它将不会被识别。


1.1.3 v-else-if 指令

v-else-if,顾名思义,充当 v-if 的“else-if 块”,可以连续使用:

示例代码:

<!-- app 是根容器  -->
<div id="app"><!---view--->
    <h2 v-if="err">网络连接错误</h2>
    <h2 v-else-if="success">网络连接成功</h2>

    <button @click="toggleError">Toggle Error</button>
    <button @click="toggleSuccess">Toggle Success</button>
</div>
<script>
    //实例化Vue对象
    const vm = new Vue({
        el: "#app",
        data: {
            err:false,
            success:false
        },
        methods: {
            toggleError(){
                this.err = !this.err
            },
            toggleSuccess(){
                this.success = !this.success
            }
        }
    })
</script>  

示例说明:

  1. 当数据中errtrue时,显示v-if所在的DOM元素, v-else-if所在的DOM元素不会显示
  2. 当数据中errfalse时,不显示v-if所在的DOM元素,
  3. 然后在根据v-else-if的判断条件是否为true,来决定是否显示所在的DOM元素


1.2 template标签

template标签, 是vue提供给我们的没有实际意义的,用来包裹元素的,


为什么需要template标签?

  1. 原因在于如果我需要多个标签同时显示或隐藏,我们就需要把这些标签包裹在同一标签里
  2. 如果不使用template标签,渲染出来结果就会多一层空标签

通过下面的示例来了解使用和不使用的不同.


1.2.1 未使用template标签

例如:

<div id="app"><!---view--->
    <div v-if="register">
        <h2>注册</h2>
        <input type="text" />
    </div>
    <div v-else>
        <h2 >登录</h2>
        <input type="text" />
    </div>

    <button @click="register = !register">{{register?"登录":"注册"}}</button>
</div>

<!-- js -->
<script>

    const vm = new Vue({
        el: "#app",
        data: {
            register: true
        }
    })
</script>

显示结果:

v-if未用template.png

示例结果说明:

  1. 通过示例发现,会多出一层无用的div标签
  2. 如果这种写法在你的项目中过多,就会导致嵌套过多无用的层级标签


1.2.2 使用template标签

template标签在渲染的时候并不会渲染template标签,这个标签本身没有实际意义:

示例代码如下:

<div id="app">
    <!-- 默认情况下在切换dom时,相同的结构会被复用,如果不需要复用,需要加上key属性, -->
    <template v-if="cut">
        <label>注册</label>
        <input type="text" key="1" />
    </template>
    <template v-else>
        <label>登录</label>
        <input type="text" key="2"/>
    </template>
    
    <button @click="register = !register">{{register?"登录":"注册"}}</button>
</div>

显示结果:

v-if使用了template.png

通过示例可以直观的了解到,template标签没有被渲染, 也没有多出一层无用的标签


1.3. 用key管理可复用的元素
1.3.1 关于vue复用元素说明:
  1. Vue 为了更高效地渲染元素,通常会复用已有元素而不是从头开始渲染。
  2. 这么做除了使 Vue 变得非常快之外,还有其它一些好处。
  3. 例如,如果你允许用户在不同的登录方式之间切换:

示例代码如下:

<div id="app"><!---view--->
    <template v-if="loginType === 'username'">
        <label>Username</label>
        <input placeholder="Enter your username">
    </template>
    <template v-else>
        <label>Email</label>
        <input placeholder="Enter your email address">
    </template>
    
    <button @click="loginType = loginType == 'username'? 'email':'username'">
        {{loginType=="username"?"邮箱登录":"用户名登录"}}
    </button>
</div>

那么在上面的代码中切换时 loginType 将不会清除用户已经输入的内容。
因为两个模板使用了相同的元素,<input> 不会被替换掉——仅仅是替换了它的 placeholder

这样也不总是符合实际需求,
有的时候就需要让vue不复用我们的DOM元素.
因此 Vue 为你提供了一种方式来表示“这两个元素是完全独立的,不要复用它们”。
只需添加一个具有唯一值的 key 属性即可:

<template v-if="loginType === 'username'">
    <label>Username</label>
    <input placeholder="Enter your username" key="username-input">
</template>
<template v-else>
    <label>Email</label>
    <input placeholder="Enter your email address" key="email-input">
</template>


2.v-show 指令

2.1 v-show 指令的基本使用

另一个根据条件展示元素的指令是 v-show 指令。用法和v-if大致一样:

示例代码:

<h1 v-show="ok">Hello!</h1>


2.2 不支持template和v-else

注意,

  1. v-show 不支持 <template> 元素,
  2. v-show 指令不支持 v-else。如果使用会报错
<template v-show="false">
    <div>我很帅</div>
    <div>我很帅</div>
    <div>我很帅</div>
    <div>我很帅</div>
</template>

此时虽然v-show是false,但是template里面的div依然会显示在网页上,同时控制台并没有报错.


3. v-if VS v-show

3.1 v-ifv-show不同

v-if 和v-show 指令都可以让元素显示或者隐藏,那么两个指令有什么不同呢?

v-if判断位假时,整个元素都会从DOM节点上删除,并不算隐藏。不会在DOM节点上占位。

<div id="app">
    <div class="login" v-if="msg">登录</div>
    <div class="register" v-else>注册</div>
</div>

不管条件真假,loginregister 两个div元素在DOM节点上只会显示一个,另外一个不满足条件的会被从节点上删除

不同的是带有 v-show 的元素始终会被渲染并保留在 DOM 中。v-show 只是简单地切换元素的 CSS 属性 display

<!-- app 是根容器  -->
<div id="app">
    <div class="login" v-show="msg">登录</div>
    <div class="register" v-show="!msg">注册</div>
</div>

v-show只是给元素添加了dispaly:block; 显示,元素即使不显示也依然在DOM节点上占位。


3.1 v-ifv-show不同总结:
  1. v-if是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。
  2. v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做,直到条件第一次变为真时,才会开始渲染条件块。
  3. v-show 就简单得多,不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。
  4. 一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。
  5. 因此,如果需要非常频繁地切换,则使用 v-show 较好;
  6. 如果在运行时条件很少改变,则使用 v-if 较好。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,639评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,277评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,221评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,474评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,570评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,816评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,957评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,718评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,176评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,511评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,646评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,322评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,934评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,755评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,987评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,358评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,514评论 2 348