接着前面的内容:https://www.cnblogs.com/yanggb/p/12577433.html

列表渲染

vue提供了一个【v-for】指令用于列表渲染(循环)。

用【v-for】指令把一个数组对应为一组元素

我们可以使用【v-for】指令基于一个数组来渲染一个列表。使用【v-for】指令需要使用【item in items】形式的特殊语法,其中items是源数据数组,而item则是被迭代的数组元素的别名。

<ul id="example-1">
<li v-for="item in items">
{{ item.message }}
</li>
</ul>
var example1 = new Vue({
el: '#example-1',
data: {
items: [
{ message: 'Foo' },
{ message: 'Bar' }
]
}
})

在【v-for】块中,我们可以访问所有父作用域的属性。此外,【v-for】指令还支持一个可选的第二参数,为当前项的索引。

<ul id="example-2">
<li v-for="(item, index) in items">
{{ parentMessage }} - {{ index }} - {{ item.message }}
</li>
</ul>
var example2 = new Vue({
el: '#example-2',
data: {
parentMessage: 'Parent',
items: [
{ message: 'Foo' },
{ message: 'Bar' }
]
}
})

当然了,你也可以使用【of】替代【in】作为分隔符,因为它更接近javascript迭代器的语法。

<div v-for="item of items"></div>

是不是像极了javascript中的【for-of】语法?

在【v-for】指令中使用对象

除了遍历数组之外,【v-for】指令还可以用于遍历一个对象的属性。

<ul id="v-for-object" class="demo">
<li v-for="value in object">
{{ value }}
</li>
</ul>
new Vue({
el: '#v-for-object',
data: {
object: {
title: 'How to do lists in Vue',
author: 'Jane Doe',
publishedAt: '2016-04-10'
}
}
})

同样的,你也可以提供第二个参数作为property的名称(key键名)。

<div v-for="(value, name) in object">
{{ name }}: {{ value }}
</div>

更多的,还可以使用第三个参数作为索引。

<div v-for="(value, name, index) in object">
{{ index }}. {{ name }}: {{ value }}
</div>

注意到遍历数组和遍历对象的差别了吗?这里有个差别就是遍历对象是支持三个参数的,分别是键值、键名和索引,而遍历数组则只支持两个参数,分别是元素和索引。

另外要注意的是,在遍历对象的时候,会按照Object.keys()的结果遍历,但是不能保证它的结果在不同的javascript引擎下都一致。

维护状态

当vue正在更新使用【v-for】指令渲染的元素列表的时候,默认采用的是【就地更新】的策略。意思就是说,如果数据项的顺序被改变,vue是不会移动dom元素来匹配数据项的顺序的,而是就地更新每个元素,并且确保它们在每个索引位置正确渲染,类似于vue1.x的【track-by="$index"】。

这个默认模式是高效的,但是只适用于不依赖子组件状态或临时dom状态(例如表单输入值)的列表渲染输出。为了给vue一个提示,以便它能跟踪每个节点的身份,从而重用和排序现有元素,你需要为每个项提供一个唯一的key属性值。

<div v-for="item in items" v-bind:key="item.id">
<!-- 内容 -->
</div>

建议尽可能在使用【v-for】指令的时候提供key属性,除非遍历输出的dom内容非常简单,或者是刻意依赖默认行为以获得性能上的提升。

因为key是vue识别节点的一个通用机制,并不是仅仅与【v-for】指令有特别关联。事实上,其还有一些别的用途,在之后的学习中会再次得到更多的了解。

此外,官方文档特别标注了,不要使用对象或数组之类的非基本类型值作为【v-for】指令的key,请用字符串或数值类型的值,否则可能导致意外的问题。

在【v-for】指令中的使用值范围

【v-for】指令也可以接受整数,在这种情况下,它会把模板重复对应次数。

<div>
<span v-for="n in 10">{{ n }} </span>
</div>

其实就是一个固定次数的循环。

在<template>上使用【v-for】指令

类似于【v-if】,你也可以利用带有【v-for】指令的<template>来循环渲染一段包含多个元素的内容,相当于循环分组。

<ul>
<template v-for="item in items">
<li>{{ item.msg }}</li>
<li class="divider" role="presentation"></li>
</template>
</ul>

因为<template>是vue模板的语法,所以并不会被渲染到最终的输出结果中。

【v-for】指令和【v-if】指令一同使用

当【v-if】指令与【v-for】指令一起使用的时候,【v-for】指令会拥有比【v-if】更高的优先级,这样的机制意味着,【v-if】指令将分别重复运行于每个【v-for】指令循环中。当你只想为部分项渲染节点的时候,这种优先级的机制会十分有用。

<li v-for="todo in todos" v-if="!todo.isComplete">
{{ todo }}
</li>

以上的代码将只会渲染出未完成的todo。

但是如果你的目的是有条件地跳过循环的执行,则需要将【v-if】指令置于外层元素(或者<template>)上。

<ul v-if="todos.length">
<li v-for="todo in todos">
{{ todo }}
</li>
</ul>
<p v-else>No todos left!</p>

总结就是,将【v-if】和【v-for】指令放在同一个元素中,相当于在循环中写if,而将【v-if】提在【v-for】指令外层,则相当于在if中写循环。

在组件使用【v-for】指令

在自定义的组件上,可以像任何普通元素一样使用【v-for】指令。

<my-component v-for="item in items" :key="item.id"></my-component>

在2.2.0+的版本,当在组件上使用【v-for】指令的时候,key是必须的,目的是使每个组件实例能独立被渲染。

在上面的例子中,并没有自动传递任何数据到组件中,这是因为组件拥有着自己的独立作用域。为了能够把迭代的数据传递到组件中,我们必须使用prop手动将数据传到组件中。

<my-component
v-for="(item, index) in items"
v-bind:item="item"
v-bind:index="index"
v-bind:key="item.id"></my-component>

不自动将item注入到组件中的原因是,这样做会使得组件与【v-for】指令的运作紧密耦合,不符合组件设计的初衷。明确组件数据的来源能够保证组件是一个独立的整体,从而使得组件能够在其他场合重复使用。

来看一个简单的todo列表的完整例子:

<div id="todo-list-example">
<form v-on:submit.prevent="addNewTodo">
<label for="new-todo">Add a todo</label>
<input
v-model="newTodoText"
id="new-todo"
placeholder="E.g. Feed the cat">
<button>Add</button>
</form>
<ul>
<li
is="todo-item"
v-for="(todo, index) in todos"
v-bind:key="todo.id"
v-bind:title="todo.title"
v-on:remove="todos.splice(index, 1)"></li>
</ul>
</div>
Vue.component('todo-item', {
template: '\
<li>\
{{ title }}\
<button v-on:click="$emit(\'remove\')">Remove</button>\
</li>\
',
props: ['title']
}) new Vue({
el: '#todo-list-example',
data: {
newTodoText: '',
todos: [
{
id: 1,
title: 'Do the dishes',
},
{
id: 2,
title: 'Take out the trash',
},
{
id: 3,
title: 'Mow the lawn'
}
],
nextTodoId: 4
},
methods: {
addNewTodo: function () {
this.todos.push({
id: this.nextTodoId++,
title: this.newTodoText
})
this.newTodoText = ''
}
}
})

注意这里的【is="todo-item"】属性,这样的写法和【<todo-item></todo-item>】的写法效果是一样的,但是可以避开一些潜在的浏览器解析错误。因为在<ul>元素里只有<li>元素会被看作有效内容,这样的写法就相当于给组件套模板,将组件里定义的<li>元素套到页面的<li>元素上。简单的理解就是规范组件的套用从而避免浏览器解析组件出错,因此这种写法在使用dom模板的时候是十分必要的。

"我还是很喜欢你,像仲夏流萤四起,弦月沉西。"

vue2.x学习笔记(八)的更多相关文章

  1. Learning ROS forRobotics Programming Second Edition学习笔记(八)indigo rviz gazebo

    中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS forRobotics Pro ...

  2. vue2.0学习笔记之路由(二)路由嵌套+动画

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. vue2.0学习笔记之路由(二)路由嵌套

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. python3.4学习笔记(八) Python第三方库安装与使用,包管理工具解惑

    python3.4学习笔记(八) Python第三方库安装与使用,包管理工具解惑 许多人在安装Python第三方库的时候, 经常会为一个问题困扰:到底应该下载什么格式的文件?当我们点开下载页时, 一般 ...

  5. Go语言学习笔记八: 数组

    Go语言学习笔记八: 数组 数组地球人都知道.所以只说说Go语言的特殊(奇葩)写法. 我一直在想一个人参与了两种语言的设计,但是最后两种语言的语法差异这么大.这是自己否定自己么,为什么不与之前统一一下 ...

  6. 【opencv学习笔记八】创建TrackBar轨迹条

    createTrackbar这个函数我们以后会经常用到,它创建一个可以调整数值的轨迹条,并将轨迹条附加到指定的窗口上,使用起来很方便.首先大家要记住,它往往会和一个回调函数配合起来使用.先看下他的函数 ...

  7. go微服务框架kratos学习笔记八 (kratos的依赖注入)

    目录 go微服务框架kratos学习笔记八(kratos的依赖注入) 什么是依赖注入 google wire kratos中的wire Providers injector(注入器) Binding ...

  8. Redis学习笔记八:集群模式

    作者:Grey 原文地址:Redis学习笔记八:集群模式 前面提到的Redis学习笔记七:主从复制和哨兵只能解决Redis的单点压力大和单点故障问题,接下来要讲的Redis Cluster模式,主要是 ...

  9. Java IO学习笔记八:Netty入门

    作者:Grey 原文地址:Java IO学习笔记八:Netty入门 多路复用多线程方式还是有点麻烦,Netty帮我们做了封装,大大简化了编码的复杂度,接下来熟悉一下netty的基本使用. Netty+ ...

  10. ROS学习笔记八:基于Qt搭建ROS开发环境

    1 前言 本文介绍一种Qt下进行ROS开发的完美方案,使用的是ros-industrial的Levi-Armstrong在2015年12月开发的一个Qt插件ros_qtc_plugin,这个插件使得Q ...

随机推荐

  1. jquery实现元素的显示和隐藏

    这个是指定表格列的隐藏的demo,其余的都大同小异了 $("#account-table tr").find($("#tcNum")).show();//sho ...

  2. 牛客网剑指offer【Python实现】——part2

    不用加减乘除做加法 写一个函数,求两个整数之和,要求在函数体内不得使用+.-.*./四则运算符号. 两个数异或:相当于每一位相加,而不考虑进位: 两个数相与,并左移一位:相当于求得进位: 将上述两步的 ...

  3. python之序列化、OS、SYS、hashlib模块

    一.序列化模块 1.序列化模块的用途 将一种数据结构转换成特殊的序列(特殊字符串,bytes),并且还可以转换回去 凡是数据通过网络传出去最终的格式必须bytes 2.json模块 json 是一种轻 ...

  4. 使用一行Python代码从图像读取文本

    处理图像不是一项简单的任务.对你来说,作为一个人,很容易看着某样东西然后马上知道你在看什么.但电脑不是这样工作的. 对你来说太难的任务,比如复杂的算术,或者一般意义上的数学,是计算机毫不费力就能完成的 ...

  5. 寻找一把进入 Alibaba Sentinel 的钥匙(文末附流程图)

    经过前面几篇文章的铺垫,我们正式来探讨 Sentinel 的 entry 方法的实现流程.即探究进入 Alibaba Sentinel 核心的一把钥匙. @ 目录 1.SphU.entry 流程分析 ...

  6. WEB缓存系统之varnish基础入门(一)

    前文我们聊了下http协议里的缓存控制机制以及varnish架构组件介绍,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/12620538.html:今天我们来聊 ...

  7. 线程安全,syncronized 用法

    1,为什么有线程安全问题? 当多个线程同时共享同一个全局变量或静态变量,做写的操作时,可能会发生数据冲突问题,也就是线程安全问题.但是做读操作是不会发生数据冲突问题. public class Tra ...

  8. 剑指offer刷题总结

    ★ 二维数组的查找 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否 ...

  9. 图解GC流程

    ​ GC流程是每一个Java开发人员都应该掌握的内容.你知道什么时候触发Minor GC?什么时候触发  Minor GC 的过程是怎么样的?Full GC 的过程又是怎么样的?这一切都要从「压死骆驼 ...

  10. 用全站 CDN 部署 Discourse 论坛

    Discourse 介绍 Discourse 是一款由 Stack Overflow 的联合创始人--Jeff Atwood,基于 Ruby on Rails 开发的开源论坛.相较于传统论坛,Disc ...