Vue.js指令是指带有特殊前缀“v-”的HTML属性,它绑定一个表达式,并将一些特性应用到DOM上。
5.1基本指令
5.1.1 v-cloak
v-clock不需要表达式,它会在Vue实例结束编译时从绑定的HTML元素上移除,经常和CSS的display:none配合使用:
<div id="app” v-clock>
{{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。
5.1.2 v-once
v-once也是一个不需要表达式的指令,作用是定义它的元素或组件只渲染一次,包括元素或组件的所有子节点。首次渲染后,不再随数据的变化重新渲染,将被视为静态内容,例如:
<div id="app">
<span v-once>{{message}}</span>
<div v-once>
<span>{{message}}</span>
</div>
<div>
<script>
var app = new Vue({
el:'#app',
data:{
message:'这是一段文本’
}
})
</script>
v-once在业务中很少使用,当你需要进一步优化性能上时,可能会用到。
5.2条件渲染指令
5.2.1 v-if、v-else-if、v-else
与JavaScript的条件语句if、else、else if类似。
Vue在渲染元素时,会尽可能地复用已有的元素而非重新渲染,比如下面这个示例就不会重新渲染:
<div id="app">
<template v-if="type==='name'">
<label>用户名:</label>
<input placeholder="输入用户名“/>
</template>
<template v-else>
<label>邮箱:</label>
<input placeholder="输入邮箱"/>
</template>
<button @click="handleToggleCick">切换输入类型</button>
</div>
<script>
var app = new Vue({
el:'#app',
data:{
tyle:'name'
},
methods:{
handleToggleClick:function(){
this.type=this.type==='name'?'mail':'name';
}
}
})
</script>
在上述代码中,点击切换按钮后,会发现input里面的值是不会发生改变的,说明input被复用了。显然我们是不希望这么做的,因此这里介绍一下Vue.js提供的key属性。
在上述代码中,添加
……
<input placeholder="输入用户名" key="name-input"/>
……
<input placeholder="输入邮箱" key="mail-input"/>
……
给两个<input>元素都增加key后,就不会复用了,切换类型时键入的内容也会被删除,不过label元素仍然是复用的,因为没有添加key属性。
5.2.2 v-show
v-show与v-if的用法基本一致,只不过v-show是改变元素的CSS属性display。当v-show表达式的值为false时,元素隐藏,查看DOM结构会看到该元素加载了内联样式。
tips:v-show不能在<tempate>中使用。
相比之下,v-if更适合条件不经常使用的场景,因为它切换开销相对较大,而v-show适用于频繁切换条件。
5.3列表渲染指令v-for
5.3.1基本用法
当需要将一个数组便利或枚举一个对象循环显示时,就会用到列表渲染指令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:'《兄弟,整理不易》'},
{name:'《可否点个赞,加个喜欢》'}
]
}
})
</script>
v-for表达式支持一个可选参数作为当前项的索引,例如
……
<li v-for="(book,index) in books">{{index+1}}、{{book.name}}</li>
……
tips:分隔符in前的语句使用括号,如果你使用过vue.js 1.x的版本,这里的index也可以由内置的$index代替,不过在2.x里取消了该用法。
v-for还可以便利对象属性,在便利对象属性时,有两个可选参数,分别是键名和索引:
<div id="app">
<ul>
<li v-for="(value,index,key) in user">
{{index}}-{{key}}-{{value}}
</li>
</ul>
</div>
<script>
var app = new Vue({
el:'#app',
data:{
user:{
name:'学习使我充实',
again:'点赞让我快乐',
answer:'啊哈哈'
}
}
})
<script>
渲染后的结果为:
·0-name:学习使我充实
·1-again:点赞让我快乐
·2-answer:啊哈哈
v-for还可以迭代整数:
<div id="app">
<span v-for="n in 10">{{n}}</span>
</div>
<script>
var app = new Vue({
el:'#app',
})
</script>
渲染后的结果为:1 2 3 4 5 6 7 8 9 10
5.3.2数组更新
Vue的核心是数据与视图的双向绑定,当我们修改数组时,Vue会检测到数据变化,所以用v-for渲染的视图也会立即更新。Vue包含了一组观察数组变异的方法,使用它们改变数组也会触发视图更新:
⚪ push()
⚪ pop()
⚪ shift()
⚪ unshift()
⚪ sort()
⚪ reverse()
使用以上方法会改变被这些方法调用的原始数组,有些方法不会改变原始数组,例如:
⚪ filter()
⚪ concat()
⚪ slice()
5.3.3过滤与排序
当你不想改变原数组,想通过一个数组的副本来做过滤或排序的显示时,可以使用计算属性来返回过滤或排序后的数组,例如:
<div id="app">
<ul>
<template v-for="book in filterBooks">
<li>书名:{{book.name}}</li>
<li>作者:{{book.author}}</li>
</template>
</ul>
</div>
<script>
var app = new Vue({
el:'#app',
data:{
{name:'vue.js实战',author:'六个周'},
{name:'vue.js实战进阶',author:'七个周'},
{name:'vue.js实战高级版',author:'八个周'}
},
computed:{
filterBooks :function(){
return this.books.filter(function(book){
return book.name.match(/ vue.js/);
});
}
}
})
</script>
上例是把书名中包含vus.js关键字的数据过滤出来,计算属性filtersBook依赖books,但是不会修改books。
5.4方法与事件
5.4.1基本用法
在事件绑定上,类似原生JavaScript的onclick等写法,也是在HTML上进行监听。例如,我们监听一个按钮的点击事件,设置一个计算器,每次点击都加1:
<div id="app">
点击次数:{{counter}}
<button @click="counter++">+1<button>
</div>
<script>
var app = new Vue({
el:'#app',
data:{
counter:0;
}
})
</script>
@click的表达式可以直接使用JavaScript语句,也可也是一个在vue实例中methods选项内的函数名,比如对上例进行扩展,再增加一个按钮,点击一次,计数器加10:
<div id="app">
点击次数:{{counter}}
<button @click="handleClick()">+1</button>
<button @click="handleClick(10)+10</button>
</div>
<script>
var app = new Vue({
el:'#app',
data:{
counter:0;
},
methods:{
handleClick:function(value){
count = value||1;
this.counter +=count;
}
}
})
</script>
tips:@click调用的方法名后handleClick可以不跟括号“()”。
Vue提供了一个特殊变量$event,用于访问原声DOM事件,例如下面的实例可以阻止链接打开:
<div id="app">
<a href="www.lmzlyl.club" @click="handleClick('禁止打开',$event)">打开链接</a>
</div>
<script>
var app = new Vue({
el:'#app',
methods:{
handleClick:function(msg,event){
event.preventDefault();
window.alert(msg);
}
}
})
</script>