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