Vue 2.0学习(六)内置指令
基本指令
1.v-cloak
v-cloak不需要表达式,它会在Vue实例结束编译时从绑定的HTML元素上移除,经常和CSS的display:none配合使用。
<div id="app" v-cloak> {{ message }} </div>
<script> var app = new Vue({ el: '#app', data: { message:'这是一段文本' } }) </script>
这是虽然已经加了指令v-cloak,但其实并没有起到任何作用,当网速较慢、Vue.js文件还没加载完时,在页面上会显示{{ message }}字样,直到Vue创建实例、编译模板时,DOM才会被替换,所以这个过程屏幕是有闪动的。只要加一句CSS就可以解决问题了
[v-cloak]{ display: none; }
在一般情况下,v-cloak是一个解决初始化慢导致页面闪动的最佳实践,对于简单的项目很实用,但是在具有工程化的项目里,比如后面学到的webpack和vue-router时,项目的HTML结构只有一个空的div元素,剩余的内容都是由路由去挂在不同组件完成的,所以不再需要v-cloak。
2.v-once
v-once也是一个不需要表达式的指令,作用是定义它的元素或组件只渲染一次,包括元素或组件的所有子节点。首次渲染后,不再随数据的变化重新渲染,将被视为静态内容。
v-once在业务中很少使用,当需要进一步优化时,可能会用到。
条件渲染指令
1.v-if、v-else-if、v-else
与JavaScript的条件语句if、else、else if类似,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>否则显示该行</p> </div>
<script> var app = new Vue({ el: '#app', data: { status: 1 } }) </script>
v-else-if要紧跟v-if,v-else要紧跟v-else-if或v-if,表达式为真时,当前元素或组件及所有子节点将被渲染,为假时被移除。如果一次判断的是多个元素,可以在Vue.js内置的<template>元素上使用条件指令,最终渲染的结果不会包含该元素。
<div id="app"> <template v-if="status === 1"> <p>这是一段文本</p> <p>这是一段文本</p> <p>这是一段文本</p> </template> </div>
<script> var app = new Vue({ el: '#app', data: { status: 1 } }) </script>
2.v-show
v-show用法与v-if基本一致,只不过v-show是改变元素的CSS属性display。当v-show表达式的值为false时,元素会隐藏,查看DOM结构会看到元素上加载了内联样式display: none;
<div id="app"> <p v-show="status === 1">当status为1时显示该行</p> </div>
<script> var app = new Vue({ el: '#app', data: { status: 2 } }) </script>
渲染后的结果为:
<p style="display: none;">当status为1时显示该行</p>
v-show不能在<template>上使用。
3.v-if与v-show的选择
v-if和v-show具有类似的功能,不过v-if才是真正的条件渲染,它会根据表达式适当地销毁或重建元素及绑定的事件或子组件。若表达式初始值为false,则一开始元素/组件并不会渲染,只有当条件第一次变为真时才开始编译。
而v-show只是简单的CSS属性切换,无论条件真与否,都会被编译。相比之下,v-if更适合条件不经常改变的场景,因为它切换开销相对较大,而v-show适用于频繁切换条件。
列表渲染指令 v-for
基本用法
当需要讲一个数组遍历或枚举一个对象循环显示时,就会用到列表渲染指令v-for。它的表达式需结合in来使用,类似item in items的形式。
<div id="app"> <ul> <li v-for="book in books">{{ book.name }}</li> </ul> </div>
<script> var app = new Vue({ el: '#app', data: { books: [ { name: '《Vue.js实战》'}, { name: '《JavaScript语言精粹》'}, { name: '《JavaScript高级程序设计》'} ] } }) </script>
在表达式中,books是数据,book是当前数组元素的别名,循环出的每个<li>内的元素都可以访问到对应的当前数据book。列表渲染也支持用of来代替in作为分隔符,它更接近JavaScript迭代器的语法。
v-for的表达式支持一个可选参数作为当前项的索引。
<div id="app"> <ul> <li v-for="(book,index) in books">{{index}} - {{ book.name }}</li> </ul> </div>
分隔符in前面的语句使用括号,第二项就是books当前项的索引。
Vue在检测到数组变化时,并不是直接重新渲染整个列表,而是最大化地复用DOM元素。替换的数组中,含有相同元素的项不会被重新渲染,因此可以大胆地用新数组来替换就数组,不用担心性能问题。
需要注意的是,以下变动的数组中,Vue是不能检测到的,也不会触发视图更新:
♦ 通过索引直接设置项,比如app.books[3] = {...}。
♦ 修改数组长度,比如app.books.length = 1。
解决第一个问题可以用两种方法实现同样的效果,第一种是使用Vue内置的set方法:
Vue.set(app.books,3,{ name: '《CSS揭秘》', author: '[希] Lea Verou' });
另一种方法:
app.books.splice(3, 1, { name: '《CSS揭秘》', author: '[希] Lea Verou' })
第二个问题也可以直接用splice来解决:
app.books.splice(1);