v-if、v-else-if、v-else
这三个指令与JavaScript的条件语句if、else、else if类似。
Vue的条件指令可以根据表达式的值在DOM中渲染或销毁元素或组件
v-if的原理:
v-if后面的条件为false时,对应的元素以及其子元素不会渲染。
也就是根本没有不会有对应的标签出现在DOM中。
<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>
<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的最大区别。
v-if
如果条件不满足,会直接不进行渲染。
v-show
无论如何都渲染,只是不满足条件是,会增加行内元素 display:none
注意,v-show 不支持 元素,也不支持 v-else。
那么如何选择呢?
一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。
注意:在写v-else-if 的时候不用再这样写了:
良好
这是没有必要的,因为上边已经判断过了。
<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 for="user">账号登录: label>
<input type="text" id="user" placeholder="请输入账号">
span>
<span v-else>
<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 for="user">账号登录: label>
<input type="text" id="user" placeholder="请输入账号" key="username">
span>
<span v-else>
<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>