一、Vue中的v-if 和 v-show

v-if、v-else-if、v-else
这三个指令与JavaScript的条件语句if、else、else if类似。
Vue的条件指令可以根据表达式的值在DOM中渲染销毁元素组件
v-if的原理:
v-if后面的条件为false时,对应的元素以及其子元素不会渲染。
也就是根本没有不会有对应的标签出现在DOM中。

1.1 v-if 决定是否渲染 基本使用:

<body>
  <div id='app'>
      <h2 v-if="true">{{message}}</h2>
      <h2 v-if="false">{{message}}</h2>
  </div>
  
  <script src='../js/vue.js'></script>
  <script>
    let vm = new Vue({
      el:'#app',
      data:{
        message:'test'
      },
    })
  </script>
</body>

注意看DOM树里边根本就没有第二个h2标签!
在这里插入图片描述

1.2 v-show 决定是否显示

<body>
  <div id='app'>
      <h2 v-show="true">{{message}}</h2>
      <h2 v-show="false">{{message}}</h2>
  </div>
  
  <script src='../js/vue.js'></script>
  <script>
    let vm = new Vue({
      el:'#app',
      data:{
        message:'test',
        isShow:true
      },
    })
  </script>
</body>

效果:
在这里插入图片描述
这里注意看,第二个元素还是被渲染到DOM树里边了的,只是被设置为不显示。
这就是v-if 和v-show的最大区别。

1.3 v-if 和 v-show的区别

v-if 如果条件不满足,会直接不进行渲染。
v-show 无论如何都渲染,只是不满足条件是,会增加行内元素 display:none

注意,v-show 不支持 元素,也不支持 v-else。

那么如何选择呢?

一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。

1.4 v-if 根据成绩返回评价

注意:在写v-else-if 的时候不用再这样写了:
<h2 v-else-if="score>=70 && score < 80">良好</h2>
这是没有必要的,因为上边已经判断过了。

<style>
  *{
    margin: 0;
    padding: 0;
    box-sizing: border-box;
  }
  [v-cloak]{
    display: none;
  }
  input{
    display: block;
    width: 100vw;
  }
</style>
<body>
  <div id='app' v-cloak>
      <input type="range" v-model='score' >
      <h2 v-if="score>=80">优秀</h2>
      <h2 v-else-if="score>=70">良好</h2>
      <h2 v-else-if="score>=60">合格</h2>
      <h2 v-else>不合格</h2>
  </div>
  
  <script src='../js/vue.js'></script>
  <script>
    let vm = new Vue({
      el:'#app',
      data:{
        score:95
      },
    })
  </script>
</body>

效果:
在这里插入图片描述
不过我们不建议这么做,因为这样会使我们的DOM树结构看起来很乱,参杂了一些逻辑运算,我们可以把它放到计算属性里边进行处理。
改进过后:

  <style>
    *{
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }
    [v-cloak]{
      display: none;
    }
    input{
      display: block;
      width: 100vw;
    }
  </style>
</head>
<body>
  <div id='app' v-cloak>
      <h2>{{result}}</h2>
  </div>
  <script src='../js/vue.js'></script>
  <script>
    let vm = new Vue({
      el:'#app',
      data:{
        score:95
      },
      computed: {
      	// es6的对象增强写法  等同于 result:function(){...}
        result(){
          let showMessage = "";
          if(this.score>=80){
            showMessage = "优秀";
          }else if(this.score>=70){
            showMessage = "良好";
          }else if(this.score>=60){
            showMessage = "合格";
          }else{
            showMessage = "不合格";
          }
          return showMessage
        }
      },
    })
  </script>
</body>

效果:
在这里插入图片描述

二、小案例 点击切换登录的类型

<body>
  <div id='app'>
      <span v-if="isUser">
        <!-- <label>账号登录: <input type="text" id="user" placeholder="请输入账号"></label> -->

        <label for="user">账号登录: </label>
        <input type="text" id="user" placeholder="请输入账号">
      </span>
      <span v-else>
        <!-- <label>邮箱登录: <input type="text" id="email" placeholder="请输入邮箱"></label> -->

        <label for="email">邮箱登录:</label>
        <input type="text" id="email" placeholder="请输入邮箱">
      </span>
      <button @click="isUser = !isUser"> 切换类型</button>
  </div>
  
  <script src='../js/vue.js'></script>
  <script>
    let vm = new Vue({
      el:'#app',
      data:{
        isUser:true
      },
    })
  </script>
</body>

效果:
在这里插入图片描述
这里牵扯到一个问题,input框中的内容为什么没有清空?
这是Vue的虚拟DOM的原因,它会在渲染的时候做出相应的处理,如果这次渲染的内容和标签 对比上次,如果没有绝对性的改变的话,它会对我们的标签进行复用,这就导致了,我们原来input里边的内容还存在的情况。
怎么解决这个问题呢?其实很简单,只需要给我们不希望进行复用的标签加上key就可以了,加上key它会把key作为一个标识,如果两个标签的key不相同,则不能服用,如果相同,则可以复用。

<body>
  <div id='app'>
      <span v-if="isUser">
        <!-- <label>账号登录: <input type="text" id="user" placeholder="请输入账号"></label> -->

        <label for="user">账号登录: </label>
        <input type="text" id="user" placeholder="请输入账号" key="username">
      </span>
      <span v-else>
        <!-- <label>邮箱登录: <input type="text" id="email" placeholder="请输入邮箱"></label> -->

        <label for="email">邮箱登录:</label>
        <input type="text" id="email" placeholder="请输入邮箱" key="emial">
      </span>
      <button @click="isUser = !isUser"> 切换类型</button>
  </div>
  
  <script src='../js/vue.js'></script>
  <script>
    let vm = new Vue({
      el:'#app',
      data:{
        isUser:true
      },
    })
  </script>
</body>

效果:
在这里插入图片描述
当然,解决的办法还有很多,比如使用隐式的label也可以达到同样的效果。

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐