###一,前言
这两天会出一份目录,对之前的几篇也会重新编排,
并补充一些遗漏的知识点,例如插值部分的过滤器等等...
在没有目录的情况下,暂时先按照自己的想法把知识点更新上来
这一篇介绍Vue的条件渲染指令,包括v-if,v-else-if,v-else,v-show
这些指令虽然都是根据条件对页面进行显示的指令,但功能和使用上还是很值得考究的
###二,v-if,v-else-if,v-else指令的简单介绍
和js语法中的条件语句if...else if...else类似,将这三个指令列为一组
Vue.js的条件指令也可以根据表达式的值,完成DOM中元素/组件的渲染和销毁
<div id="app">
<p v-if="status === 1">当status等于1时显示此行</p>
<p v-else-if="status === 2">当status等于2时显示此行</p>
<p v-else>当status既不等于1也不等于2时显示此行</p>
</div>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
status: 1
}
})
</script>
上面这个简单的例子,会根据status的值动态渲染页面完成显示
status=1:
此时DOM:
通过dev-tools工具将status改为2:
此时DOM:
从图中可以看到页面会随status值变化而同步变化,
且只显示status值对应的dom,其他dom并没有被渲染
当status由1变为2时,status=1的dom被销毁,status=2的dom被创建
###三,v-show指令的简单介绍
v-show的用法和v-if相同,功能上很相似,也是控制元素的显示和隐藏
但两者对于显示隐藏式的实现方式不同,
v-show是通过改变元素CSS属性display实现显隐效果的
<div id="app">
<p v-show="status === 1">当status等于1时显示此行</p>
</div>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
status: 1
}
})
</script>
当status=1时,元素显示:
此时DOM:
使用devtools将status值修改为2,元素隐藏
此时DOM:
我们发现当v-show表达式为false时,元素隐藏,
与v-if不同的是,这个元素依然还存在于dom中,
只是被添加了style="display: none;"实现隐藏效果
注意:
在使用上和js相似,v-else-if需要紧跟v-if,v-else要紧跟v-else-if或v-if
当表达式为真时,相应的元素/组件及所有节点将被渲染,为假时将被移除
v-show不支持语法,也不支持v-else
###四,一次判断多个元素的显示隐藏
上面介绍了v-if和v-show的简单使用和区别
但上边的例子都是对的那个元素进行显示隐藏控制
在真实项目中,往往需要一次判断控制多个元素的显示隐藏
我们可以在多个元素上添加相同的判断条件,但这样会造成代码的冗余
我们也可以在外层套一个div做v-if或v-show的显隐判断,
但这会导致渲染结果多出一个div,而这个div往往并不是我们想要的
这时,我们可以在Vue内置的元素上使用条件指令
最终渲染的结果不会包含该元素
<div id="app">
<template v-if="status === 1">
<p>项目一</p>
<p>项目二</p>
<p>项目三</p>
</template>
</div>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
status: 1
}
})
</script>
在元素上使用条件指令v-if,最终渲染的结果不包含该元素
注意:
v-show不能用于元素,无论v-show值是否为真,元素始终都会显示
###五,v-if和v-show的比较
v-if和v-show从功能上将都是实现控制显示隐藏
存在必有道理,对于v-if和v-show的选择是几乎所有Vue面试题都有的一道题
严格来说v-if才是真正的条件渲染,因为它会根据表达式创建/销毁元素及绑定事件或子组件
若初始化表达式为false,则元素/组件不会被渲染,只有当表达式第一次为真时才开始编译
v-show只是简单的CSS属性切换,不管表达式是否为真都会被编译
对于v-if和v-show的选择没有绝对的对错,这要看场景的需要
v-if更适合条件不经常变化的场景,因为频繁的创建会造成较大的开销,效率也较低
v-show更适合频繁的切换,因为dom中一直存在,只是在更改CSS而已
###六,Diff算法导致的元素/组件复用问题
现在很多网站的登录页面都支持多种登录方式:用户名,邮箱,各种第三方登录等等
现以用户名和邮箱作为两种不同类型的登录方式供用户进行切换选择
<div id="app">
<template v-if="type === 'name'">
<label>用户名:</label>
<input placeholder="请输入用户名">
</template>
<template v-if="type === 'email'">
<label>邮箱:</label>
<input placeholder="请输入邮箱">
</template>
<br>
<br>
<button @click="toggle">切换账户类型:用户名/邮箱</button>
</div>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
type:'name'
},
methods:{
toggle: function () {
this.type = this.type === 'name' ? 'email' : 'name';
}
}
})
</script>
运行结果:
点击切换按钮,显示邮箱输入:
以上测试了基本功能的实现,再做一个测试:在用户名类型的input中输入一个用户名,再点击切换按钮
通过和之前测试的观察发现:
填写用户名的情况下,切换登录类型,邮箱登录的input会使用用户名填写的value值
这是因为:
Vue在渲染元素时会使用Diff算法对已有组件进行最大限度的复用而非重新渲染,以提升效率
输入内容后切换输入类型,虽然DOM变化但内容没有改变,只替换了placeholder,说明被复用
####如果不希望这样做
有些时候,Vue的这种机制并不是我们想要的,这时可以使用Vue.js提供的key属性
由key值决定是否复用以后元素,key值必须唯一
<div id="app">
<template v-if="type === 'name'">
<label>用户名:</label>
<input placeholder="请输入用户名" key="name-input">
</template>
<template v-if="type === 'email'">
<label>邮箱:</label>
<input placeholder="请输入邮箱" key="email-input">
</template>
<br>
<br>
<button @click="toggle">切换账户类型:用户名/邮箱</button>
</div>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
type:'name'
},
methods:{
toggle: function () {
this.type = this.type === 'name' ? 'email' : 'name';
}
}
})
</script>
通过以上简单的修改,为两个元素添加key,不会再产生复用效果
当键入内容后点击切换按钮,内容不会被复用
由于
###七,结尾
关于Vue条件渲染指令的内容就先说这些,
对于key的使用更多的情况出现在v-for循环中,
下一节列表渲染指令v-for...
维护记录:
20181107:添加v-show不支持语法,也不支持v-else
20190923:修改代码风格,使代码高亮
20190927:修改错别字