case8-列表渲染
v-for的使用
我们可以用 v-for
指令基于一个数组来渲染一个列表。v-for
指令需要使用 item in items
形式的特殊语法,其中 items
是源数据数组,而 item
则是被迭代的数组元素的别名。
<ul id="example-1">
<li v-for="item in items" :key="item.message">
{{ item.message }}
</li>
</ul>
var example1 = new Vue({
el: '#example-1',
data: {
items: [
{ message: 'Foo' },
{ message: 'Bar' }
]
}
})
在 v-for
块中,我们可以访问所有父作用域的 property。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>
你也可以用 v-for
来遍历一个对象的 property。
<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 名称 (也就是键名):
<div v-for="(value, name) in object">
{{ name }}: {{ value }}
</div> //此处的name可换成其他名称
还可以用第三个参数作为索引:
<div v-for="(value, name, index) in object">
{{ index }}. {{ name }}: {{ value }}
</div>
当 Vue 正在更新使用 v-for
渲染的元素列表时,它默认使用“就地更新”的策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序,而是就地更新每个元素,并且确保它们在每个索引位置正确渲染。这个类似 Vue 1.x 的 track-by="$index"
。
这个默认的模式是高效的,但是只适用于不依赖子组件状态或临时 DOM 状态 (例如:表单输入值) 的列表渲染输出。
为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 key
attribute:
<div v-for="item in items" v-bind:key="item.id">
<!-- 内容 -->
</div>
建议尽可能在使用 v-for
时提供 key
attribute,除非遍历输出的 DOM 内容非常简单,或者是刻意依赖默认行为以获取性能上的提升。
因为它是 Vue 识别节点的一个通用机制,key
并不仅与 v-for
特别关联。后面我们将在指南中看到,它还具有其它用途。
数组更新检测
变更方法
Vue 将被侦听的数组的变更方法进行了包裹,所以它们也将会触发视图更新。这些被包裹过的方法包括:
push()
在底部插入pop() 底部删除
shift() 头部删除
unshift() 头部插入
splice() 删除第几个
sort() 排序
reverse()
在v-for里使用范围值
v-for
也可以接受整数。在这种情况下,它会把模板重复对应次数。
<div>
<span v-for="n in 10">{{ n }} </span>
</div>
实例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<Script src="vue.js"></Script>
</head>
<body>
<div id="app">
<ul>
=====================列表渲染==================
<!-- 这里的item指代数组当中的每一个元素 items为整个数组 -->
<li v-for="item in items">
{{item}}
</li>
</ul>
<hr>
<ul>
<li v-for="item in book">
{{item.code}}-{{item.name}}
</li>
</ul>
===============列表渲染:遍历对象属性===========
<ul>
<!-- 集合中每一个元素都应有唯一的key值 -->
<li v-for="(value,key) in books">
{{key}}:{{value}}
</li>
</ul>
===============在v-for中使用范围=============
<ul>
<li v-for="n in 5">
{{n}} <br>
</li>
</ul>
==============遍历表格===============
<table border="1" cellspacing="10">
<header>
<th>序号</th>
<th>姓名</th>
<th>学号</th>
<th>年龄</th>
</header>
<tbody>
<tr v-for="(stu,index) in students" v-bind:key="index"> <!-- key必须被提供 -->
<td>{{index+1}}</td>
<td>{{stu.name}}</td>
<td>{{stu.studentNo}}</td>
<td>{{stu.age}}</td>
</tr>
</tbody>
</table>
====================操作数组===================
<button v-on:click="push">push</button>
<button v-on:click="pop">pop</button>
<button v-on:click="shift">shift</button>
<button v-on:click="unshift">unshift</button>
<button v-on:click="splice">splice</button>
<button v-on:click="sort">sort</button>
</div>
</body>
<script>
var vm = new Vue({
el: '#app', //#为id选择符
data: {
items: ['A', 'B', 'C'],
books: { code: '10001', name: 'one', age: '100' },
book: [{ code: '10001', name: 'one' },
{ code: '10002', name: 'two' },
{ code: '10003', name: 'three' }],
students: [
{ name: 'Jane', studentNo: '20220308001', age: 19 },
{ name: 'Alice', studentNo: '20220308002', age: 20 },
{ name: 'James', studentNo: '20220308003', age: 18 },
{ name: 'Petter', studentNo: '20220308004', age: 20 },
],
},
methods: {
push() { //尾部插入
this.students.push({ name: 'Andy', studentNo: '20220308005', age: 100 });
},
pop() { //尾部删除
this.students.pop();
},
shift() { //头部删除
this.students.shift();
},
unshift() { //头部插入
this.students.unshift({ name: 'Eric', studentNo: '20220308006', age: 99 });
},
splice() { //指定删除
//splice有两个参数,第1个参数操作数组的起始下标,第2个参数表示要删除的元素个数
this.students.splice(1, 2);
},
sort() { //排序
},
}
})
</script>
</html>
case9-事件处理
监听事件
可以用 v-on
指令监听 DOM 事件,并在触发时运行一些 JavaScript 代码。
<div id="example-1">
<button v-on:click="counter += 1">Add 1</button>
<p>The button above has been clicked {{ counter }} times.</p>
</div>
var example1 = new Vue({
el: '#example-1',
data: {
counter: 0
}
})
事件处理方法
然而许多事件处理逻辑会更为复杂,所以直接把 JavaScript 代码写在 v-on
指令中是不可行的。因此 v-on
还可以接收一个需要调用的方法名称。
<div id="example-2">
<!-- `greet` 是在下面定义的方法名 -->
<button v-on:click="greet">Greet</button>
</div>
var example2 = new Vue({
el: '#example-2',
data: {
name: 'Vue.js'
},
// 在 `methods` 对象中定义方法
methods: {
greet: function (event) {
// `this` 在方法里指向当前 Vue 实例
alert('Hello ' + this.name + '!')
// `event` 是原生 DOM 事件
if (event) {
alert(event.target.tagName)
}
}
}
})
// 也可以用 JavaScript 直接调用方法
example2.greet() // => 'Hello Vue.js!'
内联处理器中的方法
除了直接绑定到一个方法,也可以在内联 JavaScript 语句中调用方法:
<div id="example-3">
<button v-on:click="say('hi')">Say hi</button>
<button v-on:click="say('what')">Say what</button>
</div>
new Vue({
el: '#example-3',
methods: {
say: function (message) {
alert(message)
}
}
})
有时也需要在内联语句处理器中访问原始的 DOM 事件。可以用特殊变量 $event
把它传入方法:
<button v-on:click="warn('Form cannot be submitted yet.', $event)">
Submit
</button>
methods: {
warn: function (message, event) {
// 现在我们可以访问原生事件对象
if (event) {
event.preventDefault()
}
alert(message)
}
}
实例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<Script src="vue.js"></Script>
</head>
<body>
<div id="app">
<!-- 事件处理: -->
<!-- 1、运行 JavaScript 代码,例如:counter += 1; -->
<button v-on:click="counter += 1">1、运行 JavaScript 代码,例如:counter += 1</button>
<p>The button above has been clicked {{ counter }} times.</p>
<br>
<!-- 2、传参:方法名,需要在 methods 中定义。 -->
<button v-on:click="greet">2、传参:方法名,需要在 methods 中定义。</button>
<br>
<!-- 3、在 method 方法中接收“原生事件”参数:event,例如:greet(event){} -->
<button v-on:click="greet3">3、在 method 方法中接收“原生事件”参数:event,例如:greet(event){}</button>
<br>
<!-- 4、在内联 JavaScript 语句中调用方法,例如:say('Hi') -->
<button v-on:click="say('Hi')">4、在内联 JavaScript 语句中调用方法,例如:say('Hi')</button>
<br>
<!-- 5、在内联 JavaScript 语句中访问原始的 DOM 事件,例如:say('Hi', $event) -->
<button v-on:click="say1('Hi',$event)">5、在内联 JavaScript 语句中访问原始的 DOM 事件,例如:say('Hi', $event)</button>
</div>
</body>
<script>
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!.js!!!',
counter: 0,
},
methods: {
greet: function () {
alert("'Hello'+'Vue.js'");
},
//另一种函数写法
greet3(event) {
console.log(event);
},
say(v) {
alert(v);
},
say1(str, event) {
alert(str);
console.log(event);
}
}
})
</script>
</html>