一、v-if,v-else-if,v-else

基本使用
这三个指令与JavaScript的条件语句if、else、else if类似。
Vue的条件指令可以根据表达式的值在DOM中渲染或销毁元素或组件。
代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script src="../js/vue.js"></script> 
  <div id="app">

    <h2 v-if="isShow">
       <div>132</div>
       <div>132</div>
       <div>132</div>
       <div>132</div>
       {{message}}
    </h2>
  
    <h2 v-else>v-if为false时就展示我</h2>

<!--复杂的逻辑不推荐这种方式-->
    <h2 v-if="score>=90">优秀</h2>
    <h2 v-else-if="score>=80">良好</h2>
    <h2 v-else-if="score>=60">及格</h2>
    <h2 v-else>不及格</h2>
  </div>
  <script>
  const app = new Vue({
    el: '#app',
    data: { 
      message: 'helloWorld!',
      isShow:true
    }
  });
  </script>
</body>
</html>

v-if原理
v-if后面的条件为false时,对应的元素以及其子元素不会渲染。也就是根本没有不会有对应的标签出现在DOM中。

一个案例问题
如下代码:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script src="../js/vue.js"></script>
  
  <div id="app">
    <span v-if="isUser">
      <label for="username">用户账号</label><!--点击用户帐号,焦点光标就显示在对应id的输入框中-->
      <input type="text" id="username" placeholder="用户账号" key="username">
    </span>
    
    <span v-else>
      <label for="email">用户邮箱</label>
      <input type="text" id="email" placeholder="用户邮箱" key="email">
    </span>
    <button @click="isUser=!isUser">切换登陆方式</button>
  </div>
  <script>
  const app = new Vue({
    el: '#app',
    data: { 
      message: 'helloWorld!',
      isUser:true
    }
  });
  </script>
</body>
</html>

这里的问题是因为Vue在进行DOM渲染时,出于性能考虑,会尽可能的复用已经存在的元素,而不是重新创建新的元素。
在上面的案例中,Vue内部会发现原来的input元素不再使用,直接作为else中的input来使用了。。。
解决方法:可以给标签加上一个key属性,如果其他标签的key属性值与其一样则就不进行复用,如果存在与其key属性值相同的还是会考虑复用。
v-show
v-show的用法和v-if非常相似,也用于决定一个元素是否渲染。

v-if和v-show对比:v-if和v-show都可以决定一个元素是否渲染,那么开发中我们如何选择呢?
1.v-if当条件为false时,压根不会有对应的元素在DOM中。
2.v-show当条件为false时,仅仅是将元素的display属性设置为none而已。

开发中如何选择呢?
1.当需要在显示与隐藏之间切片很频繁时,使用v-show。
2.当只有一次切换时,通常使用v-if。

二、循环遍历

v-for使用
当我们有一组数据需要进行渲染时,我们就可以使用v-for来完成。
v-for的语法类似于JavaScript中的for循环。
格式如下:item in items的形式。
代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script src="../js/vue.js"></script>
  
  <div id="app">
    <ul>
      <!--在遍历时,获取索引值-->
      <li v-for="(item,index) in names">{{index}}-{{item}}</li>
    </ul>
  </div>
  <script>
  const app = new Vue({
    el: '#app',
    data: { 
      message: 'helloWorld!',
      names:['saber','acher','lancer','zhangheng']
    }
  });
  </script>
</body>
</html>

v-for遍历对象
代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script src="../js/vue.js"></script>
  <div id="app">
    <!--遍历对象获取属性值-->
    <ul>
      <li v-for="item in info ">
       {{item}}
      </li>
    </ul>
    <!--遍历对象获取属性值和属性,应为value相对更重要,所以只有一个值时,就是value,而且第一个值才是value-->
    <ul>
      <li v-for="(value,item,index) in info ">
       {{item}}-{{value}}-{{index}}
      </li>
    </ul>
  </div>
  <script>
  const app = new Vue({
    el: '#app',
    data: { 
      message: 'helloWorld!',
      info:{
        name:'zhangheng',
        age:18,
        height:1.88
      }
    }
  });
  </script>
</body>
</html>

组件的key
官方推荐我们在使用v-for时,给对应的元素或组件添加上一个:key属性。

为什么需要这个key属性呢(了解)?
这个其实和Vue的虚拟DOM的Diff算法有关系。
这里我们借用React’s diff algorithm中的一张图来简单说明一下:

key.png

当某一层有很多相同的节点时,也就是列表节点时,我们希望插入一个新的节点。我们希望可以在B和C之间加一个F,Diff算法默认执行起来是这样的。
即把C更新成F,D更新成C,E更新成D,最后再插入E,是不是很没有效率?
所以我们需要使用key来给每个节点做一个唯一标识。Diff算法就可以正确的识别此节点,找到正确的位置区插入新的节点。
检测数组更新
因为Vue是响应式的,所以当数据发生变化时,Vue会自动检测数据变化,视图会发生对应的更新。
Vue中包含了一组观察数组编译的方法,使用它们改变数组也会触发视图的更新。
shuzu.png

三、v-model表单绑定

表单控件在实际开发中是非常常见的。特别是对于用户信息的提交,需要大量的表单。Vue中使用v-model指令来实现表单元素和数据的双向绑定。
代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script src="../js/vue.js"></script>
  
  <div id="app">
    <!--
      通过v-model实现双向绑定,此时我们修改input中的内容,data中的message也会改变了,
      另外textarea这个标签也适用于这个方法
    -->
    <input type="text" v-model="message">
    {{message}}
  </div>
  <script>
  const app = new Vue({
    el: '#app',
    data: { 
      message: 'helloWorld!'
    }
  });
  </script>
</body>
</html>

当我们在输入框输入内容时因为input中的v-model绑定了message,所以会实时将输入的内容传递给message,message发生改变。当message发生改变时,因为上面我们使用Mustache语法,将message的值插入到DOM中,所以DOM会发生响应的改变。
所以,通过v-model实现了双向的绑定。

v-model原理
v-model其实是一个语法糖,它的背后本质上是包含两个操作:

  • v-bind绑定一个value属性
  • v-on指令给当前元素绑定input事件

代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script src="../js/vue.js"></script>
  
  <div id="app">
    <!-- <input type="text" v-model="message"> -->
    <!--其实v-model可以看作下面的操作-->
    <input type="text" :value="message"><!--这里实现了一次单向绑定,即修改data中的message可修改此value,但是修改value就不能改掉data中的message-->
    <input type="text" :value="message" v-on:input="changeMessage"><!--这里的v-on:input表示监听输入事件,注意:这里不带括号就默认传入一个事件对象到方法中-->
    <!--这样就实现了双向绑定,下面是另一种简写,没使用方法,直接用的表达式-->
    <input type="text" :value="message" v-on:input="message=$event.target.value">
    <h2>{{message}}</h2>
  </div>
  <script>
  const app = new Vue({
    el: '#app',
    data: { 
      message: 'helloWorld!'
    },
    methods: {
      changeMessage(event){
          this.message=event.target.value;//将修改值赋给message
      }
    },
    
  });
  </script>
</body>
</html>

v-model结合radio使用

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script src="../js/vue.js"></script>
  
  <div id="app">
    <label for="male">
      <input type="radio" id="male"  value="男" v-model="sex">男<!--加一个name使选项互斥,如果加上了v-model,name属性可以不加-->
    </label>
    <label for="female">
      <input type="radio" id="female"  value="女" v-model="sex">女
    </label>
    <h2>你选择的是:{{sex}}</h2>
  </div>
  <script>
  const app = new Vue({
    el: '#app',
    data: { 
      message: 'helloWorld!',
      sex:''
    }
  });
  </script>
</body>
</html>

v-model结合checkbox使用

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script src="../js/vue.js"></script>
  
  <div id="app">
    <!--单选框-->
    <label for="license">
      <input type="checkbox" id="license" v-model="isAgree">同意协议
    </label>
    <h2>你选择的是:{{isAgree}}</h2>
    <button :disabled="!isAgree">下一步</button>
    <br>
    <!--多选框-->
    <input type="checkbox" value="篮球" v-model="hobbies">篮球
    <input type="checkbox" value="足球" v-model="hobbies">足球
    <input type="checkbox" value="排球" v-model="hobbies">排球
    <h2>你的爱好:{{hobbies}}</h2>

     <!--值的动态绑定-->
     <label v-for="item in originHobbies" :for="item">
      <input type="checkbox" :value="item" :id="item" v-model="hobbies">{{item}}
    </label>
  </div>
  <script>
  const app = new Vue({
    el: '#app',
    data: { 
      message: 'helloWorld!',
      isAgree:false,
      hobbies:[],
      originHobbies:['台球','冰球','火球']
    }
  });
  </script>
</body>
</html>

v-model结合select使用

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script src="../js/vue.js"></script>
  
  <div id="app">
    <!--选择1个-->
    <select name="abc" id="" v-model="fruit" >
      <option value="苹果" >苹果</option>
      <option value="香蕉" >香蕉</option>
      <option value="榴莲" >榴莲</option>
      <option value="梨子" >梨子</option>
    </select>
    <h2>你选了个{{fruit}}</h2>
    <br>
    <select name="abc" id="" v-model="fruits" multiple><!--加了这个属性就可以多选了,但是要按住ctrl再点击-->
      <option value="苹果" >苹果</option>
      <option value="香蕉" >香蕉</option>
      <option value="榴莲" >榴莲</option>
      <option value="梨子" >梨子</option>
    </select>
    <h2>你选了这些:{{fruits}}</h2>
  </div>
  <script>
  const app = new Vue({
    el: '#app',
    data: { 
      message: 'helloWorld!',
      fruit:'香蕉',
      fruits:[]
    }
  });
  </script>
</body>
</html>

v-model的修饰符
lazy修饰符:
默认情况下,v-model默认是在input事件中同步输入框的数据的。也就是说,一旦有数据发生改变对应的data中的数据就会自动发生改变。lazy修饰符可以让数据在失去焦点或者回车时才会更新。

number修饰符:
默认情况下,在输入框中无论我们输入的是字母还是数字,都会被当做字符串类型进行处理。但是如果我们希望处理的是数字类型,那么最好直接将内容当做数字处理。number修饰符可以让在输入框中输入的内容自动转成数字类型。

trim修饰符:
如果输入的内容首尾有很多空格,通常我们希望将其去除。trim修饰符可以过滤内容左右两边的空格。


<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script src="../js/vue.js"></script>
  
  <div id="app">
    <!--
      1.lazy修饰符的使用,使绑定值在失去焦点或者敲回车后再生效
    -->
    <input type="text" v-model.lazy="message">
    <h2>{{message}}</h2>
  <br>
    <!--2.number修饰符,可以将绑定的值转换为number类型,因为v-model默认转过去的值会转为string类型-->
    <input type="number" v-model.number="age">
    <h2>{{typeof age}}-{{age}}</h2>
  <br>
    <!--3.修饰符: trim ,可以过滤掉内容两边空格-->
  <input type="text" v-model.trim="name">
  <h2>您输入的名字:{{name}}</h2>
  </div>
  <script>
  const app = new Vue({
    el: '#app',
    data: { 
      message: 'helloWorld!',
      age:18,
      name:''
    }
  });
  </script>
</body>
</html>
Last modification:August 12, 2020
如果觉得我的文章对你有用,请随意赞赏