前面的话

  上一篇介绍了Vue的模板内容,而对于一般的模板引擎来说,除了模板内容,还包括模板逻辑。常用的模板逻辑包括条件和循环。本文将详细介绍Vue模板逻辑

条件渲染

  在Vue中,实现条件逻辑依靠条件指令,包括v-if、v-else、v-else-if这三个

【v-if】

  根据表达式的值的真假条件渲染元素。赋值为true时,将元素插入DOM中, 否则对应元素从DOM中移除

  因此,Vue里的v-if指令类似于模板引擎的if条件语句

<div id="app" v-if="seen">
{{ message }}
</div>

  上面代码中,如果"seen"的值为true,则"#app"元素显示,否则将从DOM中移除

<script>
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!',
seen:true
}
})
</script>

  如果想切换多个元素,可以把一个<template>元素当做包装元素,并在上面使用v-if。最终的渲染结果不会包含<template>元素

<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】

  表示 v-if 的 “else if 块”。可以链式调用。前一兄弟元素必须有 v-if 或 v-else-if

【v-else】

  为 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关联

Vue模板逻辑的更多相关文章

  1. [Vue源码]一起来学Vue模板编译原理(一)-Template生成AST

    本文我们一起通过学习Vue模板编译原理(一)-Template生成AST来分析Vue源码.预计接下来会围绕Vue源码来整理一些文章,如下. 一起来学Vue双向绑定原理-数据劫持和发布订阅 一起来学Vu ...

  2. [Vue源码]一起来学Vue模板编译原理(二)-AST生成Render字符串

    本文我们一起通过学习Vue模板编译原理(二)-AST生成Render字符串来分析Vue源码.预计接下来会围绕Vue源码来整理一些文章,如下. 一起来学Vue双向绑定原理-数据劫持和发布订阅 一起来学V ...

  3. sublime SublimeTmpl 添加vue模板

    sublime2安装时候报错在control中加下面的代码 重新启动,可以进行安装 import urllib2,os; pf='Package Control.sublime-package'; i ...

  4. Vue模板内容

    前面的话 如果只使用Vue最基础的声明式渲染的功能,则完全可以把Vue当做一个模板引擎来使用.本文将详细介绍Vue模板内容 概述 Vue.js使用了基于HTML的模板语法,允许声明式地将DOM绑定至底 ...

  5. (英文版)VScode一键生成.vue模板

    1. 安装vscode,官网地址 2.安装一个插件,识别vue文件 插件库中搜索Vetur,下图中的第一个,点击安装(Install) 3.新建代码片段 点击Code(代码)-Preferences( ...

  6. vscode写vue模板--代码片段

    Ctrl+Shift+P打开命令输入 snippet (打开用户代码片段) 在输入vue(选择代码片段的语言) 如果搜索不到,安装一个插件 vueHelper 如果搜索到复制粘贴以下代码 { &quo ...

  7. webpack4.x加vue模板文件简单还原vue-cli

    1.首先 npm init -y 创建一个项目 2.安装vue npm install vue --save 3.然后安装webpack 注意如果全局没有还要安装全局的webpack和webpack- ...

  8. vs code 快速生成vue 模板

    vs code 快速生成vue 模板 1.使用快捷Ctrl + Shift + P唤出控制台,然后输入snippets并选择.(或 文件>首选项>用户代码片断里面,输入 vue.json ...

  9. Vue基础系列(三)——Vue模板中的数据绑定语法

    写在前面的话: 文章是个人学习过程中的总结,为方便以后回头在学习. 文章中会参考官方文档和其他的一些文章,示例均为亲自编写和实践,若有写的不对的地方欢迎大家和我一起交流. VUE基础系列目录 < ...

随机推荐

  1. 《javascript高级程序设计》笔记三

    第三章 基本概念 任何语言的核心必然会描述这门语言最基本的工作原理.这部分内容对我们来说,读起来很乏味,甚至会产生困意,但这部分内容却是重要的!我有幸拜读<JavaScript高级程序设计> ...

  2. ASP.NET Core 源码学习之 Options[4]:IOptionsMonitor

    前面我们讲到 IOptions 和 IOptionsSnapshot,他们两个最大的区别便是前者注册的是单例模式,后者注册的是 Scope 模式.而 IOptionsMonitor 则要求配置源必须是 ...

  3. 【Android Developers Training】 35. 序言:分享文件

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

  4. Linux中使用京东代码库JDCode创建私有Git仓库

    国外Git经常被墙,所以目光转向国内.目前,云存储真的是很热,有很多公司在做. 看了一下,CSDN,开源中国,淘宝,京东,Gitcafe都在搞.淘宝只支持SVN. JD号称提供1G免费空间,而且支持私 ...

  5. IE的hack问题浅谈

    *我一直以为是IE7的专属选择. 开始,我以为是bug ,怎么可能会有+号.一定是哪位同事写错了.找了度娘才知道自己的不足.原来也是可以的. 后来,通过ie8和ie7来调整自己的css.也感觉不用ha ...

  6. Javascript 类继承

    Js继承 JavaScript并不是真正面向对象的语言,是基于对象的,没有类的概念. 要想实现继承,可以用js的原型prototype机制或者用apply和call方法去实现 /** 声明一个基础父类 ...

  7. 《javascript高级程序设计》笔记七

    第五章 引用类型(三) 今天首先说的就是Function类型.下面就是定义函数的两种方法,第一种使用函数声明语法定义,第二种使用函数表达式定义.这两种定义函数的方式几乎没有什么区别. function ...

  8. voa 2015.4.29

    Nepal has declared three days of mourning for the victims of Saturday's 7.8 magnitude earthquake tha ...

  9. MongoDB数据库基础操作

    前面的话 为了保存网站的用户数据和业务数据,通常需要一个数据库.MongoDB和Node.js特别般配,因为Mongodb是基于文档的非关系型数据库,文档是按BSON(JSON的轻量化二进制格式)存储 ...

  10. 在Docker Hub上查找可用的Image映像

    任何人都可以创建Docker Image映像,你可以浏览Docker Hub来查找这些Image映像. 定位Whalesay 映像 打开你的浏览器,浏览Docker Hub: Docker Hub包含 ...