Vue 指令v-if、v-show、v-once和v-cloak
前面两篇文章中总结了v-bind、v-on、v-for、v-model等指令的相关内容,这篇文章将总结v-if、v-show、v-once、v-cloak等指令的内容。
(1)条件渲染:v-if,v-else,v-else-if
v-if条件指令可以根据表达式的值在DOM中渲染或销毁元素/组件,下面是v-if的用法示例:
<div id="app">
<div v-if="see">
现在你能看到我,如果改变app.see的值为false,你就看不到我啦!
</div>
</div>
<script>
var app=new Vue({
el:"#app",
data:{
see:true
}
})
</script>
1.在<template>元素上使用v-if条件渲染分组
上面的代码中,v-if只能控制一个元素,要想控制多个元素,可以把<template>当作包裹元素,并在<template>上使用v-if。最终渲染的结果不包含template,如果使用div作为包裹元素,最终渲染的结果会包含div:
<div id="app">
<template v-if="is">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
</template>
<div v-if="is">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
</div>
</div>
<script>
var app = new Vue({
el: "#app",
data: {
is:true
},
})
</script>
渲染的结果为:
<div id="app">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
</div>
</div>
2.可以使用v-else指令来表示v-if的"else"块:
<div id="app">
<div v-if="is">我是v-if块</div>
<div v-else>我是v-else块</div>
</div>
<script>
var app = new Vue({
el: "#app",
data: {
is: true
},
})
</script>
渲染结果为:
<div id="app">
<div>我是v-if块</div>
</div>
v-else的元素必须紧跟在带v-if或者v-else-if的元素后面,否则它不会被识别。
3.可以使用v-else-if充当v-if的的"else-if"块
<div id="app">
<div v-if="is===0">is的值为0</div>
<div v-else-if="is===1">is的值为1</div>
<div v-else-if="is===2">is的值为2</div>
<div v-else-if="is===3">is的值为3</div>
<div v-else>is的值不是0,1,2,3中的一个</div>
</div>
<script>
var app = new Vue({
el: "#app",
data: {
is: 1
},
})
</script>
渲染的结果为:
<div id="app">
<div>is的值为1</div>
</div>
v-else-if的元素必须紧跟在带v-if的元素后面,否则它不会被识别。
(2)条件渲染:v-show
v-show的用法与v-if的用法基本上是一致的:
<div id="app">
<div v-show="is">你好!</div>
</div>
<script>
var app = new Vue({
el: "#app",
data: {
is: true
},
})
</script>
渲染结果为:
<div id="app">
<div>你好!</div>
</div>
下面是v-show与v-if的不同:
1.v-show不能在<template>上使用
v-if可以在<template>上使用,控制多个元素;而v-show是不支持<template>的。
<div id="app">
<template v-show="is">
<div>1</div>
<div>2</div>
<div>3</div>
</template>
</div>
<script>
var app = new Vue({
el: "#app",
data: {
is: false
},
})
</script>
<div id="app">
<template v-show="is">
<div>1</div>
<div>2</div>
<div>3</div>
</template>
</div>
<script>
var app = new Vue({
el: "#app",
data: {
is: true
},
})
</script>
无论is的值为false还是true,渲染的结果都是:
<div id="app">
<div>1</div>
<div>2</div>
<div>3</div>
</div>
2.v-show切换css的display属性,v-if会让元素销毁和重建
v-show:不管初始条件是true还是false,元素总会被渲染。在true与false相互变化时,它只是简单的切换css的display属性。
v-if:在true与false的切换过程中,会让元素销毁和重建。如果初始条件为false,它什么也不做,直到第一次条件变为true时才会渲染元素,如果之后条件又变为false,那么它会销毁元素。
<div id="app">
<div v-if="is">这个元素使用了v-if</div>
<div v-show="is">这个元素使用了v-show</div>
</div>
<script>
var app = new Vue({
el: "#app",
data: {
is: true
},
})
</script>
渲染结果为:
<div id="app">
<div>这个元素使用了v-if</div>
<div>这个元素使用了v-show</div>
</div>
当app.is的值变为false时,渲染结果为:
<div id="app">
<div style="display:none;">这个元素使用了v-show</div>
</div>
一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要频繁地切换条件,使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。
(3)v-once
v-once是一个不需要表达式的指令。
定义了v-once的元素或组件只渲染一次,包括元素或组件的所有子节点。首次渲染后,当数据改变时,插值处的内容不会再更新,绑定的类、id等也不会更新。
<div id="app" >
<div v-once v-bind:class="left">{{message}}</div>
<div v-once><span v-bind:id="left">{{message}}</span></div>
</div>
<script>
var app = new Vue({
el: "#app",
data: {
message: "你好!",
left:"up"
},
});
app.message="123";
app.left="down";
</script>
渲染的结果为:
<div id="app" >
<div class="up">你好!</div>
<div><span id="up">你好!</span></div>
</div>
(4)v-cloak
v-cloak是一个不需要表达式的指令。
v-cloak 可以防止页面加载时出现 vue.js 的变量名,需要与CSS的display:done一起配合使用。
<div id="app">
{{message}}
</div>
<script>
var app = new Vue({
el: "#app",
data: {
message: "你好!"
},
})
</script>
对于上面代码,当网速较慢、Vue.js文件还没有加载完成时,页面上会显示{{message}}字样,直到Vue创建实例、编译模板时,DOM才会被替换,所以在网速较慢时,这个过程中屏幕是有闪动的。v-cloak 与CSS的display:done一起配合使用可以解决这个问题:
为元素加上v-cloak指令:
<div id="app" v-cloak>
{{message}}
</div>
在CSS中添加:
[v-cloak] {
display: none;
}
以上操作的意思是,包含 v-cloak属性的 html 标签在页面初始化时会被隐藏,在 Vue实例结束编译时,v-cloak 属性会被自动去除,对应的标签就会变为可见。也就不会再出现闪动的问题。
在一般情况下,v-cloak是解决初始化慢导致页面闪动的最佳实践,对于简单的项目很实用。但在具有工程化的项目中,可能不再需要v-cloak。
参考:
1.Vue.js官方文档
2.《Vue.js实战》