接着前面的内容: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. 浅析二分搜索树的数据结构的实现(Java 实现)

    目录 树结构简介 二分搜索树的基础知识 二叉树的基本概念 二分搜索树的基本概念 二分搜索树的基本结构代码实现 二分搜索树的常见基本操作实现 添加操作 添加操作初步实现 添加操作改进 查询操作 遍历操作 ...

  2. 不再忍受龟速 Github,你也可以试试在云开发上部署个人博客!

    Hexo 是被大家广泛使用的静态博客系统, 除了在 Github Pages 部署以外,现在你有了一个新的选择,那就是使用云开发静态网站功能来部署啦! 云开发(CloudBase)是一款云端一体化的产 ...

  3. 使用tensorflow的softmax进行mnist识别

    tensorflow真是方便,看来深度学习需要怎么使用框架.如何建模- ''' softmax classifier for mnist created on 2019.9.28 author: vi ...

  4. python字典(dict)

    1.字典dict定义 初始化 key-value键值对的数据的集合,可变.无序.key不重复(哈希.唯一) 1> d = dict() 或者 d = {} # -*- coding:utf-8 ...

  5. 双连通分量 Road Construction POJ - 3352

    @[双连通分量] 题意: 有一个 n 个点 m 条边的无向图,问至少添加几条边,能让该图任意缺少一条边后还能相互连通. 双连通分量定义: 在无向连通图中,如果删除该图的任何一个结点都不能改变该图的连通 ...

  6. cat userlist

    cat命令 Linux下的一个文本输出命令,通常用于观看某个文件的内容 功能: 1.一次显示整个文件 $ cat filename 2.从键盘创建一个文件 $ cat > filename 只能 ...

  7. HTML特殊转义字符——特殊符号

    干货,见下图: 后期我会陆续更一些JavaScript的文章,大家可以一起学习交流.

  8. EOS基础全家桶(六)账号管理

    简介 本篇我们会学习最基本的账号相关的操作,包括了创建账号和查询,关于账号资源的操作因为必须先部署系统合约,所以我们会留到后面单独写一篇来讲解. 6-EOS基础全家桶(六)账号管理 简介 账号介绍 账 ...

  9. iOS开发|从小公司到进大厂,我的进阶学习之旅!

    iOS高级进发 OC源码下载地址 苹果开发文档 如何阅读苹果开发文档 GNUstep是GNU计划的项目之一,它将Cocoa的OC库重新开源实现了一遍 源码地址:http://www.gnustep.o ...

  10. Java代理笔记

    代理顾名思义,就是一个中间层,当我们要使用某个方法时,不直接调用,而是告诉代理,让代理替我们去请求方法,并返回结果.在这个过程中,我们只知道代理执行并返回给了我们操作结果,至于它有没有其他操作并不知道 ...