此学习教程是对官方教程的解析,
本章节主要涉及到的官方教程地址:
条件渲染
上一章 :Vue入门实战教程(三)—— 视图层:模板及指令
我们可以用 v-for 指令基于一个数组来渲染一个列表。v-for 指令需要使用 item in items 形式的特殊语法,其中 items 是源数据数组,而 item 则是被迭代的数组元素的别名。
在 v-for 块中,我们可以访问所有父作用域的 property。v-for 还支持一个可选的第二个参数,即当前项的索引。
第一个的参数:item 被迭代的数组元素
第二个的参数:index 作为索引
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
head>
<body>
<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>
body>
html>
变更方法:会变更调用了这些方法的原始数组。
Vue 将被侦听的数组的变更方法进行了包裹,所以它们也将会触发视图更新。这些被包裹过的方法包括:
push()
pop()
shift()
unshift()
splice()
sort()
reverse()
非变更方法:不会变更原始数组,而总是返回一个新数组。
例如 filter()、concat() 和 slice()
当使用非变更方法时,可以用新数组替换旧数组:
example1.items = example1.items.filter(function (item) {
return item.message.match(/Foo/)
})
你也可以用 v-for 来遍历一个对象的 property。
第一个的参数:value 对象的 property值
第二个的参数:name 对象的 property 名称 (也就是键名)
第三个的参数:index 作为索引
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
head>
<body>
<ul id="v-for-object">
<li v-for="(value, name, index) in object">
{{ index }}. {{ name }}: {{ value }}
li>
ul>
<script>
var example2 = new Vue({
el: '#v-for-object',
data: {
object: {
title: 'How to do lists in Vue',
author: 'Jane Doe',
publishedAt: '2016-04-10'
}
}
})
script>
body>
html>
v-for 也可以接受整数。在这种情况下,它会把模板重复对应次数。
第一个的参数:item 第几次重复,以1开始
第二个的参数:index 作为索引,以0开始
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
head>
<body>
<ul id="example">
<li v-for="(item,index) in 10">{{index}}.{{item}}li>
ul>
<script>
var example2 = new Vue({
el: '#example'
})
script>
body>
html>
如果数据项的顺序被改变,Vue 默认将不会移动 DOM 元素来匹配数据项的顺序,而是就地更新每个元素,并且确保它们在每个索引位置正确渲染。但只适用于 不 依 赖 子 组 件 状 态 或 临 时 D O M 状 态 ( 例 如 : 表 单 输 入 值 ) 的 列 表 渲 染 输 出 。 \color{red}{不依赖子组件状态或临时 DOM 状态 (例如:表单输入值) 的列表渲染输出。} 不依赖子组件状态或临时DOM状态(例如:表单输入值)的列表渲染输出。
特点:
为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素。
特点:
基于两个模式完全相反的特点,所以官方建议尽可能在使用 v-for 时提供 key attribute,除非遍历输出的 DOM 内容非常简单,或者是刻意依赖默认行为以获取性能上的提升。
例子(使用和不使用v-bind:key来比较):
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
head>
<body>
<ul id="example">
<li v-for="(item, index) in items">
{{ index }} - id[{{ item.id }}] - message[{{ item.message }}]
li>
ul>
<script>
var max_num = 10000;
var items = [];
for(var i=0; i<max_num; i++){
var im = {};
im["id"] = ""+i;
im["message"] = "Foo";
items.push(im);
}
var beforeUpdateTime = null;
var updatedTime = null;
var vm = new Vue({
el: '#example',
data: {
items: items
},
beforeUpdate: function () {
beforeUpdateTime = new Date().getTime();
console.log("数据更新前时间:"+beforeUpdateTime);
},
updated: function () {
updatedTime = new Date().getTime();
console.log("数据更新后渲染完成时间:"+updatedTime);
console.log("耗时:"+(updatedTime-beforeUpdateTime)+"ms");
}
})
script>
body>
html>
不使用key:
例子(使用和不使用v-bind:key来比较):
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
head>
<body>
<div id="app">
<div>
<input type="text" v-model="name">
<button @click="add">添加button>
div>
<ul>
<li v-for="(item, i) in list">
<input type="checkbox"> {{item.name}}
li>
ul>
div>
<script>
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: {
name: '',
newId: 3,
list: [
{ id: 1, name: 'a' },
{ id: 2, name: 'b' },
{ id: 3, name: 'c' }
]
},
methods: {
add() {
//注意这里是unshift
this.list.unshift({ id: ++this.newId, name: this.name })
this.name = ''
}
}
});
script>
body>
html>
不使用key:
先选中选项b后,在列表数据头部添加选项d, 视图更新后, 选项b的选中状态变到了a上
使用key:
先选中选项b后,在列表数据头部添加选项d, 视图更新后, 选项b仍然维持选中状态
可以看到没有key不绑定子组件状态, 而有key绑定子组件状态。
两个约束:
当在组件上使用 v-for 时,key 是必须的
任何数据都不会被自动传递到组件里,因为组件有自己独立的作用域。为了把迭代数据传递到组件里,我们要使用v-bind指令和组件的props进行绑定:
例子:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
head>
<body>
<ul id="app">
<my-component
v-for="(im, i) in items"
v-bind:item="im"
v-bind:index="i"
v-bind:key="im.id"
>my-component>
ul>
<script>
Vue.component('my-component', {
template: '{{ index }} - id[{{ item.id }}] - message[{{ item.message }}] ',
props: ['item', 'index']
})
var vm = new Vue({
el: '#app',
data: {
items: [
{ id: 1, message: 'Foo1' },
{ id: 2, message: 'Foo2' },
{ id: 3, message: 'Foo3' }
]
}
});
script>
body>
html>
处于同一节点,v-for 的优先级比 v-if 更高,即:
先 执 行 v − f o r 循 环 , 再 执 行 v − i f 判 断 \color{red}{先执行v-for循环, 再执行v-if判断} 先执行v−for循环,再执行v−if判断
如果想先判断再循环,将 v-if 置于v-for所在元素的外层元素 (或 ) 上
本章节教程结束。
全部教程地址:Vue入门实战教程 | 寒于水学习网
下一章:Vue入门实战教程(四)—— 模型层:数据
特定模板语法实战:
Vue特定模板语法实战(一):Class和Style绑定
Vue特定模板语法实战(二):条件渲染
Vue特定模板语法实战(三):列表渲染
Vue特定模板语法实战(四):事件处理
Vue特定模板语法实战(五):表单输入绑定