Vue.js 内置指令

回顾一下第2.2节,我们己经介绍过指令(Directive)的概念了,Vue.js的指令是带有特殊前缀v-的HTML特性,它绑定一个表达式,并将一些特性应用到DOM上。
其实我们已经用到过很多Vue内置的指令,比如v-html、v-pre,还有上一章的v-bind。
本章将继续介绍Vue.js中更多常用的内置指令。

5.1 基本指令

5.1.1 v-cloak

v-cloak不需要表达式,它会在Vue实例结束编译时从绑定的HTML元素上移除,经常和CSS的display:none;配合使用:

 1 <div id="app" v-cloak>
 2     {{message}}
 3 </div>
 4 
 5 <script>
 6     var app = new Vue({
 7         el: "#app",
 8         data: {
 9             message: "这是一段文本"
10         }
11     });
12 </script>

这时虽然已经加了指令v-cloak,但其实并没有起到任何作用。
当网速较慢、Vue.js文件还没加载完时,在页面上会显示{{message}}的字样。
直到Vue创建实例、编译模板时,DOM才会被替换,所以这个过程屏幕是有闪动的。
只要加一句CSS就可以解决这个问题了:

1 <style>
2     [v-cloak] {
3         display: none;
4     }
5 </style>

在一般情况下,v-cloak是一个解决初始化慢导致页面闪动的最佳实践,对于简单的项目很实用,但是在具有工程化的项目里,比如后面进阶篇将介绍webpack和vue-router时,项目的HTML结构只有一个空的div元素,剩余的内容都是由路由去挂载不同组件完成的,所以不再需要v-cloak。

5.1.2 v-once

v-once也是一个不需要表达式的指令,作用是定义它的元素或组件只渲染一次,包括元素或组件的所有子节点。
首次渲染后,不再随数据的变化重新渲染,将被视为静态内容,例如:

 1 <div id="app">
 2     <span v-once>{{message}}</span>
 3     <div v-once>
 4         <span>{{message}}</span>
 5     </div>
 6 </div>
 7 
 8 <script>
 9     var app = new Vue({
10         el: "#app",
11         data: {
12             message: "这是一段文本"
13         }
14     });
15 </script>

v-once在业务中也很少使用,当你需要进一步优化性能时,可能会用到。

5.2 条件渲染指令

5.2.1 v-if、v-else-of、v-else

与JavaScript的条件语句if、else、else if类似,Vue.js的条件指令可以根据表达式的值在DOM中渲染或销毁元素/组件。
例如:

 1 <div id="app">
 2     <p v-if="status===1">当status为1时显示此行</p>
 3     <p v-else-if="status===2">当status为2时显示此行</p>
 4     <p v-else>否则显示此行</p>
 5 </div>
 6 
 7 <script>
 8     var app = new Vue({
 9         el: "#app",
10         data: {
11             status: 1
12         }
13     });
14 </script>

v-else-if要紧跟v-if,v-else要紧跟v-else-if或v-if。
表达式的值为true时,当前元素/组件及所有子节点将被渲染,为false时被移除。
如果一次判断的是多个元素,可以在Vue.js内置的元素上使用条件指令,最终渲染的结果不包含钙元素。
例如:

 1 <div id="app">
 2     <template v-if="status===1">
 3         <p>这是一段文本</p>
 4         <p>这是一段文本</p>
 5         <p>这是一段文本</p>
 6     </template>
 7 </div>
 8 
 9 <script>
10     var app = new Vue({
11         el: "#app",
12         data: {
13             status: 1
14         }
15     });
16 </script>

Vue在渲染元素时,出于效率考虑,会尽可能地复用已有的元素而非重新渲染。
比如下面的示例:

 1 <div id="app">
 2     <template v-if="type==='name'">
 3         <label for="name">用户名:</label>
 4         <input type="text" id="name" name="name" placeholder="请输入用户名">
 5     </template>
 6     <template v-else>
 7         <label for="mail">邮箱:</label>
 8         <input type="text" id="mail" name="mail" placeholder="请输入邮箱">
 9     </template>
10     <button type="button" @click="handleToggleClick">切换输入类型</button>
11 </div>
12 
13 <script>
14     var app = new Vue({
15         el: "#app",
16         data: {![在这里插入图片描述](https://img-blog.csdnimg.cn/20190429164606121.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1dhbmdaaGFvTG9uZ2pr,size_16,color_FFFFFF,t_70)
17             type: "name"
18         },
19         methods: {
20             handleToggleClick: function() {
21                 this.type = this.type === "name" ? "mail" : "name";
22             }
23         }
24     });
25 </script>

如下所示,键入内容后,点击切换按钮,虽然DOM变了,但是之前在输入框键入的内容并没有改变,只是替换了placeholder的内容,说明元素被复用了。
Vue.js 内置指令_第1张图片Vue.js 内置指令_第2张图片

如果你不希望这样做,可以使用Vue.js提供的key属性,它可以让你自己决定是否要复用元素,key的值必须是唯一的。
例如:

1 <div id="app">
 2     <template v-if="type==='name'">
 3         <label for="name">用户名:</label>
 4         <input type="text" id="name" name="name" key="name-input" placeholder="请输入用户名">
 5     </template>
 6     <template v-else>
 7         <label for="mail">邮箱:</label>
 8         <input type="text" id="mail" name="mail" key="mail-input" placeholder="请输入邮箱">
 9     </template>
10     <button type="button" @click="handleToggleClick">切换输入类型</button>
11 </div>
12 
13 <script>
14     var app = new Vue({
15         el: "#app",
16         data: {
17             type: "name"
18         },
19         methods: {
20             handleToggleClick: function() {
21                 this.type = this.type === "name" ? "mail" : "name";
22             }
23         }
24     });
25 </script>

给两个元素都增加key后,就不会复用了,切换类型时键入的内容也会被删除,不过元素仍然是被复用的,因为没有添加key属性。

5.2.2 v-show

v-show的用法与v-if基本一致,只不过v-show是改变元素的CSS属性display。
当v-show表达式的值为false时,元素会隐藏,查看DOM结构会看到元素上加载了内联样式display:none。
例如:

 1 <div id="app">
 2     <p v-show="status===1">当status为1时显示此行</p>
 3 </div>
 4 
 5 <script>
 6     var app = new Vue({
 7         el: "#app",
 8         data: {
 9             status: 2
10         }
11     });
12 </script>

渲染后的结果为:

1 <div id="app">
2     <p style="display: none;">当status为1时显示此行</p>
3 </div>
提示:
v-show不能在