10-不得不学的Vue.js基础之列表渲染
前端 · 2020-07-22 ·
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>列表渲染</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11/dist/vue.js"></script>
</head>
<body>
<div id="app">
<!--1.用 v-for 把一个数组对应为一组元素:v-for 指令需要使用 item in items 形式的特殊语法-->
<ul>
<li v-for="item in items" :key="item.message">
{{ item.message }}
</li>
</ul>
<hr />
<!--1.2在 v-for 中,我们可以访问所有的父作用域的 property。还支持可选的第二个参数(当前项的索引)-->
<ul>
<li v-for="(item,index) in items" :key="item.message">
{{parentMsg}}-{{index}}-{{ item.message }}
</li>
</ul>
<hr />
<!--也可以使用of 代替in作为分隔符-->
<ul>
<li v-for="item of items" :key="item.message">
{{ item.message }}
</li>
</ul>
<hr />
<!--2.在 v-for里遍历对象-->
<ul id="v-for-object">
<li v-for="value in object">
{{ value }}
</li>
</ul>
<hr />
<!--2.1在 v-for里遍历对象,还支持第二个参数property名称(也就是键名),以及第三个参数作为索引-->
<div v-for="(value, name, index) in object">
{{index}}-{{ name }}: {{ value }}
</div>
<!--3.数组更新检测-->
<!--3.1.变更方法:Vue将被侦听的数组的变更方法进行了包裹,所以他们也将会触发视图更新。这些被包裹过的方法包括:
//向数组的末尾添加一个或多个元素,并返回新的长度。
3.1.1 push()
//用于删除并返回数组的最后一个元素。
3.1.2 pop()
//用于删除并返回数组的第一个元素。
3.1.3 shift()
//向数组的开头添加一个或多个元素,并返回新的长度。
3.1.4 unshift()
//向数组中添加/删除项目,然后返回被删除的项目。
//splice(index,howmany,item1,...,itemX)
//index:必需。整数,规定添加/删除项目的位置,使用负数可从数组结尾处规定位置。
//howmany:必需。要删除的项目数量。如果设置为 0,则不会删除项目。
//item1, ..., itemX 可选。向数组添加的新项目。
3.1.5 splice()
//用于对数组的元素进行排序。
3.1.6 sort()
//用于颠倒数组中元素的顺序
3.1.7 reverse()
-->
<!--3.2.替换数组:变更方法,会变更原始数组。相比之下有非变更方法,例如:filter()、concat()和slice()。他们不会变更原始数组,而总是返回一个新数组。当使用非变更方法时,可以用新的数组替换旧数组:
app.items = app.items.filter(function (item) {
return item.message.match(/Monday/)
})
-->
<!--4.显示过滤/排序后的结果:有时,我们想要显示一个数组经过过滤或者排序后的版本,而不实际变更或重置原始数据,在这用情况下,可以使用Vue提供的computed 属性或methods 方法-->
<hr />
<!--4.1.创建一个计算属性,来返回过滤后或排序后的数组-->
<ul>
<li v-for="n in evenNumbers">{{n}}</li>
</ul>
<!--4.2.在计算属性不适用的情况下,还可以使用一个方法。-->
<ul v-for="set in sets">
<li v-for="n in even(set)">{{ n }}</li>
</ul>
<!--5.在 v-for 里使用值范围:v-for 也可以接受整数。在这种情况下,它会把模板重复对应次数。-->
<div>
<span v-for="n in 10">{{ n }} </span>
</div>
<!--6.在 <template> 上使用 v-for:类似于 v-if,你也可以利用带有 v-for 的 <template> 来循环渲染一段包含多个元素的内容-->
<ul>
<template v-for="item in items">
<li>{{ item.message }}</li>
</template>
</ul>
<!--7.v-for 与 v-if 一同使用:注意我们不推荐在同一元素上使用v-if 和 v-for-->
<!--当他们处于同一节点,v-for的优先级比v-if更高,这意味着 v-if 将分别重复运行于每个v-for循环中-->
<ul>
<li v-for="todo in todos" v-if="!todo.isComplete">
{{ todo }}
</li>
</ul>
<!--而如果你的目的是有条件的跳过循环的执行,那么可以将v-if置于外层元素(或<template>)上。-->
<ul v-if="todos.length">
<li v-for="todo in todos">
{{ todo }}
</li>
</ul>
<p v-else>No todos left!</p>
<!--8.在组件上使用 v-for-->
<!--在自定义组件上,你可以像在任何普通元素上一样使用 v-for-->
<my-component v-for="list in lists" v-bind:key="list.id" v-bind:list="list"></my-component>
<!--2.2.0+ 的版本里,当在组件上使用 v-for 时,key 现在是必须的。-->
<!--任何数据都不会被自动传递到组件里,因为组件有自己独立的作用域。为了把迭代数据传递到组件里,我们要使用 prop-->
<my-component2 v-for="(list,index) in lists" v-bind:key="'c-2'+list.id" v-bind:list="list" v-bind:index="index"></my-component2>
<hr>
<!--不自动将 item 注入到组件里的原因是,这会使得组件与 v-for 的运作紧密耦合。明确组件数据的数据来源能够使组件在其他场合重复使用。-->
<div id="todos">
<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>
<!--注意这里的 is="todo-item" attribute。这种做法在使用 DOM 模板时是十分必要的,因为在 <ul> 元素内只有 <li> 元素会被看作有效内容。这样做实现的效果与 <todo-item> 相同,但是可以避开一些潜在的浏览器解析错误。-->
</div>
<script>
//注册全局组件my-component!
Vue.component('my-component',{
props:['list'],
template:`
<div>
{{list.message}}
</div>
`
});
//注册全局组件my-component2!
Vue.component('my-component2',{
props:['list','index'],
template:`
<div>
{{index}}-{{list.message}}
</div>
`
});
//注册全局组件my-component2!
Vue.component('todo-item', {
template: `
<li>
{{ title }}
<button v-on:click="$emit('remove')">Remove</button>
</li>
`,
props: ['title']
});
// 全局对象
var vm = new Vue({
el: "#app",
data: {
parentMsg:"Parent",
items: [
{ message: 'Monday' },
{ message: 'Tuesday' },
{ message: 'Wednesday' }
],
object: {
title: 'How to do lists in Vue',
author: 'Jane Doe',
publishedAt: '2016-04-10'
},
numbers:[1,2,3,4,5,6,7],
sets:[[ 1, 2, 3, 4, 5 ], [6, 7, 8, 9, 10]],
todos:[
{wtd:'go to collage',isComplete:true},
{wtd:'go to work',isComplete:true},
{wtd:'graze sheep',isComplete:false}
],
lists: [
{ id:1,message: 'Monday' },
{ id:2,message: 'Tuesday' },
{ id:3,message: 'Wednesday' }
],
newTodoText: '',
todos: [
{
id: 1,
title: 'Do the dishes',
},
{
id: 2,
title: 'Take out the trash',
},
{
id: 3,
title: 'Mow the lawn'
}
],
nextTodoId: 4
},
computed:{
evenNumbers:function(){
return this.numbers.filter(function(number){
return number%2 === 0
})
}
},
methods:{
even:function(numbers){
return numbers.filter(function (number) {
return number % 2 === 0
})
},
addNewTodo: function () {
this.todos.push({
id: this.nextTodoId++,
title: this.newTodoText
})
this.newTodoText = ''
}
}
});
</script>
</body>
</html>
以下是测试数据:
- {{ item.message }}
- {{parentMsg}}-{{index}}-{{ item.message }}
- {{ item.message }}
- {{ value }}
{{index}}-{{ name }}: {{ value }}
- {{n}}
- {{ n }}
{{ n }}
- {{ item.message }}
- {{ todo }}
- {{ todo }}
No todos left!