上一篇介绍了Vue的模板内容,而对于通常的模板引擎来讲,除了模板内容,还包括模板逻辑。经常使用的模板逻辑包括条件和循环。本文将详细介绍Vue模板逻辑html
在Vue中,实现条件逻辑依靠条件指令,包括v-if、v-else、v-else-if这三个vue
【v-if】数组
根据表达式的值的真假条件渲染元素。赋值为true时,将元素插入DOM中, 不然对应元素从DOM中移除app
所以,Vue里的v-if指令相似于模板引擎的if条件语句性能
<div id="app" v-if="seen"> {{ message }} </div>
上面代码中,若是"seen"的值为true,则"#app"元素显示,不然将从DOM中移除this
<script> var app = new Vue({ el: '#app', data: { message: 'Hello Vue!', seen:true } }) </script>
若是想切换多个元素,能够把一个<template>
元素当作包装元素,并在上面使用v-if
。最终的渲染结果不会包含<template>
元素spa
<div id="app"> <template v-if="ok"> <h1>Title</h1> <p>Paragraph 1</p> <p>Paragraph 2</p> </template> </div>
<script> var app = new Vue({ el: '#app', data:{ ok:true } }) </script>
【v-else-if】3d
表示 v-if
的 “else if 块”。能够链式调用。前一兄弟元素必须有 v-if
或 v-else-if
code
【v-else】component
为 v-if
或者 v-else-if
添加 “else 块”。 前一兄弟元素必须有 v-if
或 v-else-if
下面代码中,当type='A'时,显示内容为A的div;当type='B'时,显示内容为B的div;当type='C'时,显示内容为C的div;不然,显示内容为D的div
<div v-if="type === 'A'">A</div> <div v-else-if="type === 'B'">B</div> <div v-else-if="type === 'C'">C</div> <div v-else>D</div>
<script> var app = new Vue({ el: "#app", data: { type:'A' } }) </script>
Vue会尽量高效地渲染元素,一般会复用已有元素而不是从头开始渲染。这么作,除了使 Vue 变得很是快以外,还有一些有用的好处
例如,若是容许用户在不一样的登陆方式之间切换
<div id="app"> <template v-if="loginType === 'username'"> <label>Username</label> <input placeholder="输入用户名"> </template> <template v-else> <label>Email</label> <input placeholder="输入邮箱地址"> </template> <div> <button @click="toggle">切换登陆方式</button> </div> </div>
<script> var app = new Vue({ el: '#app', data:{ loginType:'username' }, methods:{ toggle(){ if(this.loginType === 'username'){ this.loginType = ''; }else{ this.loginType = 'username'; } } } }) </script>
【key属性】
这样也不老是符合实际需求,因此Vue提供了一种方式来声明“这两个元素是彻底独立的——不要复用它们”。只需添加一个具备惟一值的key
属性便可
<div id="app"> <template v-if="loginType === 'username'"> <label>Username</label> <input placeholder="输入用户名" key="username-input"> </template> <template v-else> <label>Email</label> <input placeholder="输入邮箱地址" key="email-input"> </template> <div> <button @click="toggle">切换登陆方式</button> </div> </div>
<script> var app = new Vue({ el: '#app', data:{ loginType:'username' }, methods:{ toggle(){ if(this.loginType === 'username'){ this.loginType = ''; }else{ this.loginType = 'username'; } } } }) </script>
如今,每次切换时,输入框都将被从新渲染
[注意]<label>
元素仍然会被高效地复用,由于它们没有添加 key
属性
【v-show】
根据表达式的真假值,切换元素的display
属性。当v-show被赋值为true时,元素显示;不然,元素被隐藏
v-show和v-if指令都有元素显隐的功能,但其原理并不相同。v-if的元素显隐会将元素从DOM删除或插入;而v-show则只是改变该元素的display是否为none
[注意]v-show
不支持 <template>
语法,也不支持 v-else
v-if vs v-show
v-if
是“真正的”条件渲染,由于它确保在切换过程当中条件块内的事件监听器和子组件适当地被销毁和重建。v-if
是惰性的:若是在初始渲染时条件为假,则什么也不作——直到条件第一次变为真,才开始渲染条件块
而v-show
就简单得多——无论初始条件是什么,元素老是会被渲染,而且只是简单地基于CSS进行切换
通常来讲, v-if
有更高的切换开销,而v-show
有更高的初始渲染开销。所以,若是须要很是频繁地切换,则使用v-show
较好;若是在运行时条件不太可能改变,则使用v-if
较好
<div id="app"> <div v-if="num > 0">if</div> <div v-show="num > 0">show</div> </div>
上面代码中,若是num>0,则内容为if和内容为show的div都显示;不然都不显示
<script> var app = new Vue({ el: "#app", data: { num: 1 } }) </script>
上图所示,当num=0时,内容为if的div直接从DOM移除,而内容为show的div的display为none
【v-for】
v-for指令基于源数据屡次渲染元素或模板块,包含如下用法
数组迭代
用 v-for
指令根据一组数组的选项列表进行渲染。 v-for
指令须要以 item in items
形式的特殊语法, items
是源数据数组而且 item
是数组元素迭代的别名
v-for="item in items"
<ul id="example-1"> <li v-for="item in items"> {{ item.message }} </li> </ul>
<script> var example1 = new Vue({ el: '#example-1', data: { items: [ {message: 'Foo' }, {message: 'Bar' } ] } }) </script>
在v-for
块中,拥有对父做用域属性的彻底访问权限。v-for
还支持一个可选的第二个参数为当前项的索引
v-for="(item, index) in items"
<ul id="example-2"> <li v-for="(item, index) in items"> {{ parentMessage }} - {{ index }} - {{ item.message }} </li> </ul>
<script> var example2 = new Vue({ el: '#example-2', data: { parentMessage: 'Parent', items: [ { message: 'Foo' }, { message: 'Bar' } ] } }) </script>
也能够用 of
替代 in
做为分隔符,它是最接近JS迭代器的语法
<ul id="example-2"> <li v-for="(item, index) of items"> {{ parentMessage }} - {{ index }} - {{ item.message }} </li> </ul>
<script> var example2 = new Vue({ el: '#example-2', data: { parentMessage: 'Parent', items: [ { message: 'Foo' }, { message: 'Bar' } ] } }) </script>
和v-if
模板同样,也能够用带有v-for
的<template>
标签来渲染多个元素块
<ul id="example-2"> <template v-for="item in items"> <li>{{ item.message }}</li> <li>abc</li> </template> </ul>
<script> var example2 = new Vue({ el: '#example-2', data: { items: [ { message: 'Foo' }, { message: 'Bar' } ] } }) </script>
对象迭代
能够用 v-for
经过一个对象的属性来迭代,第二个参数为键名,第三个参数为索引
v-for="(value, key, index) in object"
<ul id="repeat-object" class="demo"> <li v-for="(value, key, index) in object"> {{ index }}. {{ key }} : {{ value }} </li> </ul>
<script> new Vue({ el: '#repeat-object', data: { object: { firstName: 'John', lastName: 'Doe', age: 30 } } }) </script>
整数迭代
v-for
也能够取整数。在这种状况下,它将重复屡次模板
[注意]整数迭代是从1开始,而不是从0开始的
<div id="example"> <span v-for="n in 10">{{ n }} </span> </div>
<script> var example = new Vue({ el: '#example' }) </script>
【组件】
在自定义组件里,能够像任何普通元素同样用v-for
<my-component v-for="item in items" :key="item.id"></my-component>
[注意]2.2.0+ 的版本里,当在组件中使用 v-for
时,key
如今是必须的
然而不能自动传递数据到组件里,由于组件有本身独立的做用域。为了传递迭代数据到组件里,要用 props
不自动注入 item
到组件里的缘由是,由于这使得组件会紧密耦合到 v-for
如何运做。在一些状况下,明确数据的来源可使组件可重用
<div id="example"> <my-component v-for="(item,index) in items" :msg="item.message" :index="index" :key="item.id"></my-component> </div>
<script> // 注册 Vue.component('my-component', { template: '<div>{{index}}.{{msg}}</div>', props:['index','msg'] }) // 建立根实例 new Vue({ el: '#example', data(){ return { items: [ {id:1, message: 'Foo' }, {id:2, message: 'Bar' }, {id:3, message: 'Baz' }, ] } } }) </script>
【v-for with v-if】
当它们处于同一节点,v-for
的优先级比v-if
更高,这意味着v-if
将分别重复运行于每一个v-for
循环中。当想为仅有的一些项渲染节点时,这种优先级的机制会十分有用
<ul id="example"> <li v-for="item in items" v-if="item.isShow"> {{ item.message }} </li> </ul>
<script> var example = new Vue({ el: '#example', data: { items: [ {isShow: true,message: 'Foo' }, {isShow: false,message: 'Bar' }, {isShow: true,message: 'Baz' } ] } }) </script>
若是要有条件地跳过循环的执行,那么将 v-if
置于包装元素 (或 <template>
)上
<ul id="example" v-if="isShow"> <li v-for="(item,index) in items" > {{ item.message }} </li> </ul>
<script> var example = new Vue({ el: '#example', data: { isShow:true, items: [ {message: 'Foo' }, {message: 'Bar' }, {message: 'Baz' } ] } }) </script>
【key】
当Vue.js用v-for
正在更新已渲染过的元素列表时,它默认用 “就地复用” 策略。若是数据项的顺序被改变,Vue将不是移动DOM元素来匹配数据项的顺序, 而是简单复用此处每一个元素,而且确保它在特定索引下显示已被渲染过的每一个元素
这个默认的模式是高效的,可是只适用于不依赖子组件状态或临时DOM状态(如表单输入值)的列表渲染输出
为了给Vue一个提示,以便它能跟踪每一个节点的身份,从而重用和从新排序现有元素,须要为每项提供一个惟一key
属性。理想的key
值是每项都有惟一id。它的工做方式相似于一个属性,因此须要用 v-bind
来绑定动态值
<div v-for="item in items" :key="item.id"> <!-- 内容 --> </div>
建议尽量使用v-for
来提供 key
,除非迭代DOM内容足够简单,或者要依赖于默认行为来得到性能提高。key是Vue识别节点的一个通用机制,key
并不特别与v-for
关联