Vue.js 实战教程 V2.x(10)列表渲染

10列表渲染

10.1用 v-for 把数组对应为元素

<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‘ }

]

}

})

访问父作用域的属性和当前项的索引。

<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‘ }

]

}

})

10.2在 v-for 里使用对象

new Vue({

el: ‘#v-for-object‘,

data: {

object: {

title: ‘How to do lists in Vue‘,

author: ‘Jane Doe‘,

publishedAt: ‘2016-04-10‘

}

}

})

<ul id="v-for-object" class="demo">

<li v-for="value in object">

{{ value }}

</li>

</ul>

第二个的参数作为键名:

<div v-for="(value, name) in object">

{{ name }}: {{ value }}

</div>

第三个参数作为索引:

<div v-for="(value, name, index) in object">

{{ index }}. {{ name }}: {{ value }}

</div>

10.3维护状态

为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 key 属性:

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

<!-- 内容 -->

</div>

10.4数组更新检测

变异方法 (mutation method)

Vue 将被侦听的数组的变异方法进行了包裹,所以它们也将会触发视图更新。这些被包裹过的方法包括:

push()

pop()

shift()

unshift()

splice()

sort()

reverse()

你可以打开控制台,然后对前面例子的 items 数组尝试调用变异方法。比如 example1.items.push({ message: ‘Baz‘ })。

替换数组

example1.items = example1.items.filter(function (item) {

return item.message.match(/Foo/)

})

10.5对象变更检测注意事项

还是由于 JavaScript 的限制,Vue 不能检测对象属性的添加或删除:

var vm = new Vue({

data: {

a: 1

}

})// `vm.a` 现在是响应式的

vm.b = 2// `vm.b` 不是响应式的

对于已经创建的实例,Vue 不允许动态添加根级别的响应式属性。但是,可以使用 Vue.set(object, propertyName, value) 方法向嵌套对象添加响应式属性。例如,对于:

var vm = new Vue({

data: {

userProfile: {

name: ‘Anika‘

}

}

})

你可以添加一个新的 age 属性到嵌套的 userProfile 对象:

Vue.set(vm.userProfile, ‘age‘, 27)

你还可以使用 vm.$set 实例方法,它只是全局 Vue.set 的别名:

vm.$set(vm.userProfile, ‘age‘, 27)

有时你可能需要为已有对象赋值多个新属性,比如使用 Object.assign() 或 _.extend()。在这种情况下,你应该用两个对象的属性创建一个新的对象。所以,如果你想添加新的响应式属性,不要像这样:

Object.assign(vm.userProfile, {

age: 27,

favoriteColor: ‘Vue Green‘

})

你应该这样做:

vm.userProfile = Object.assign({}, vm.userProfile, {

age: 27,

favoriteColor: ‘Vue Green‘

})

10.6显示过滤/排序后的结果

有时,我们想要显示一个数组经过过滤或排序后的版本,而不实际改变或重置原始数据。在这种情况下,可以创建一个计算属性,来返回过滤或排序后的数组。

例如:

<li v-for="n in evenNumbers">{{ n }}</li>

data: {

numbers: [ 1, 2, 3, 4, 5 ]

},computed: {

evenNumbers: function () {

return this.numbers.filter(function (number) {

return number % 2 === 0

})

}

}

在计算属性不适用的情况下 (例如,在嵌套 v-for 循环中) 你可以使用一个方法:

<li v-for="n in even(numbers)">{{ n }}</li>

data: {

numbers: [ 1, 2, 3, 4, 5 ]

},methods: {

even: function (numbers) {

return numbers.filter(function (number) {

return number % 2 === 0

})

}

}

10.7在 v-for 里使用值范围

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

<div>

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

</div>

10.8在 <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>

10.9 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>

10.10在组件上使用 v-for

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

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

然而,任何数据都不会被自动传递到组件里,因为组件有自己独立的作用域。为了把迭代数据传递到组件里,我们要使用 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 = ‘‘

}

}

})

完整代码:

10 列表渲染1.html

<!DOCTYPE html>

<html>

<head>

<title>列表渲染</title>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

</head>

<body>

<ul id="example-1">

<li v-for="item in items">

{{ item.message }}

</li>

</ul>

<ul id="example-2">

<li v-for="(item, index) in items">

{{ parentMessage }} - {{ index }} - {{ item.message }}

</li>

</ul>

<script>

var example1 = new Vue({

el: ‘#example-1‘,

data: {

items: [

{ message: ‘Foo‘ },

{ message: ‘Bar‘ }

]

}

})

var example2 = new Vue({

el: ‘#example-2‘,

data: {

parentMessage: ‘Parent‘,

items: [

{ message: ‘Foo‘ },

{ message: ‘Bar‘ }

]

}

})

</script>

</body>

</html>

10 列表渲染2.html

<!DOCTYPE html>

<html>

<head>

<title>列表渲染</title>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

</head>

<body>

<ul id="v-for-object" class="demo">

<li v-for="value in object">

{{ value }}

</li>

<br>

<div v-for="(value, name) in object">

{{ name }}: {{ value }}

</div>

<br>

<div v-for="(value, name, index) in object">

{{ index }}. {{ name }}: {{ value }}

</div>

</ul>

<script>

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>

10 列表渲染3.html

<!DOCTYPE html>

<html>

<head>

<title>列表渲染</title>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

</head>

<body>

<div id="app">

id:<input type="text" v-model="id">

name:<input type="text" v-model="name">

<button @click="add">add</button>

<p v-for="item in items" v-bind:key="item.id">

<input type="checkbox">

{{item.id}} {{item.name}}

</p>

</div>

<script>

var vm = new Vue({

el: "#app",

data: {

id:"",

name:"",

items:[

{id:1, name:"zhangsan"},

{id:2, name:"lisi"}

]

},

methods: {

add(){

this.items.unshift({id:this.id, name:this.name})

}

}

})

</script>

</body>

</html>

10 列表渲染4.html

<!DOCTYPE html>

<html>

<head>

<title>列表渲染</title>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

</head>

<body>

<div id="app">

<p v-for="item in items">

{{item.message}}

</p>

<button @click="filter">filter</button>

</div>

<script>

var vm = new Vue({

el: "#app",

data: {

items:[

{message:"Foo"},

{message:"Bar"}

]

},

methods: {

filter(){

this.items = this.items.filter(function (item) {

return item.message.match(/Foo/)

})

}

}

})

</script>

</body>

</html>

10 列表渲染5.html

<!DOCTYPE html>

<html>

<head>

<title>列表渲染</title>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

</head>

<body>

<div id="app">

<p v-for="item in items">

{{item}}

</p>

</div>

<script>

var vm = new Vue({

el: "#app",

data: {

items: [‘a‘, ‘b‘, ‘c‘]

}

})

// vm.items[1] = ‘x‘ // 不是响应性的

// vm.items.length = 2 // 不是响应性的

// Vue.set

// Vue.set(vm.items, 1, ‘x‘)

// Array.prototype.splice

// vm.items.splice(1, 1, ‘x2‘)

// vm.$set(vm.items, 1, ‘x3‘)

vm.items.splice(3)

</script>

</body>

</html>

10 列表渲染6.html

<!DOCTYPE html>

<html>

<head>

<title>列表渲染</title>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

</head>

<body>

<div id="app">

{{a}} {{b}}

</div>

<script>

var vm = new Vue({

el: "#app",

data: {

a: 1,

b: ‘‘

}

})// `vm.a` 现在是响应式的

vm.b = 2// `vm.b` 不是响应式的

</script>

</body>

</html>

10 列表渲染7.html

<!DOCTYPE html>

<html>

<head>

<title>列表渲染</title>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

</head>

<body>

<div id="app">

{{userProfile.name}}<br>

{{userProfile.age}}<br>

{{userProfile.favoriteColor}}

</div>

<script>

var vm = new Vue({

el: "#app",

data: {

userProfile: {

name: ‘DaQiang‘

}

}

})

// Vue.set(vm.userProfile, ‘age‘, 18)

// vm.$set(vm.userProfile, ‘age‘, 18)

vm.userProfile = Object.assign({}, vm.userProfile, {

age: 18,

favoriteColor: ‘Green‘

})

</script>

</body>

</html>

10 列表渲染8.html

<!DOCTYPE html>

<html>

<head>

<title>列表渲染</title>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

</head>

<body>

<div id="app">

<li v-for="n in evenNumbers">{{ n }}</li>

</div>

<script>

var vm = new Vue({

el: "#app",

data: {

numbers: [ 1, 2, 3, 4, 5 ]

},

computed: {

evenNumbers: function () {

return this.numbers.filter(function (number) {

return number % 2 === 0

})

}

}

})

</script>

</body>

</html>

10 列表渲染9.html

<!DOCTYPE html>

<html>

<head>

<title>列表渲染</title>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

</head>

<body>

<div id="app">

<li v-for="n in even(numbers)">{{ n }}</li>

</div>

<script>

var vm = new Vue({

el: "#app",

data: {

numbers: [ 1, 2, 3, 4, 5 ]

},

methods: {

even: function (numbers) {

return numbers.filter(function (number) {

return number % 2 === 0

})

}

}

})

</script>

</body>

</html>

10 列表渲染10.html

<!DOCTYPE html>

<html>

<head>

<title>列表渲染</title>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

</head>

<body>

<div id="app">

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

</div>

<script>

var vm = new Vue({

el: "#app"

})

</script>

</body>

</html>

10 列表渲染11.html

<!DOCTYPE html>

<html>

<head>

<title>列表渲染</title>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

</head>

<body>

<div id="app">

<ul>

<template v-for="item in items">

<li>{{ item.msg }}</li>

<li class="divider" role="presentation">Hi</li>

</template>

</ul>

</div>

<script>

var vm = new Vue({

el: "#app",

data: {

items:[

{msg:"Hello"},

{msg:"World"}

]

}

})

</script>

</body>

</html>

10 列表渲染12.html

<!DOCTYPE html>

<html>

<head>

<title>列表渲染</title>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

</head>

<body>

<div id="app">

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

{{ todo.name }}

</li>

</div>

<script>

var vm = new Vue({

el: "#app",

data: {

todos:[

{name: ‘张三‘, isComplete:false},

{name: ‘李四‘, isComplete:false}

]

}

})

</script>

</body>

</html>

10 列表渲染13.html

<!DOCTYPE html>

<html>

<head>

<title>列表渲染</title>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

</head>

<body>

<div id="app">

<ul v-if="todos.length">

<li v-for="todo in todos">

{{ todo.name }}

</li>

</ul>

<p v-else>No todos left!</p>

</div>

<script>

var vm = new Vue({

el: "#app",

data: {

todos:[

{name: ‘张三‘},

{name: ‘李四‘}

]

}

})

</script>

</body>

</html>

10 列表渲染14.html

<!DOCTYPE html>

<html>

<head>

<title>列表渲染</title>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

</head>

<body>

<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>

<script>

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 = ‘‘

}

}

})

</script>

</body>

</html>

欢迎观看视频教程:https://ke.qq.com/course/432961?tuin=36914f34,如有疑问,请加QQ群665714453交流讨论。

原文地址:https://www.cnblogs.com/daqiang123/p/11368415.html

时间: 2024-11-01 14:51:21

Vue.js 实战教程 V2.x(10)列表渲染的相关文章

热烈庆祝《Vue.js 实战教程 V2.x(一)基础篇》上线了!

课程简介 课程地址:https://ke.qq.com/course/432961 机构名称:大华软件学院 授课讲师:大强老师 课程名称:Vue.js 实战教程 V2.x(一)基础篇 课程简介:包括前端发展史.Vue.js简介.第一个Vue.js程序.安装环境和Vue.Vue实例.模板语法.计算属性和侦听器.Class与Style绑定.条件渲染.列表渲染.事件处理.表单输入绑定.组件基础等等. 适合人群: 1.初出茅庐,想学习前端开发的同学: 2.没用过Vue.js,想学习更多框架的同学: 3.

Vue.js 实战教程 V2.x(13)事件处理

13组件基础 13.1基本示例 Vue 组件的示例: // 定义一个名为 button-counter 的新组件 Vue.component('button-counter', { data: function () { return { count: 0 } }, template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>' }) 组件是可复用的 Vue

Vue.js 实战教程 V2.x(8)Class与Style绑定

8 Class与Style绑定 操作元素的 class 列表和内联样式是数据绑定的一个常见需求. 8.1绑定HTML Class 对象语法 我们可以传给 v-bind:class 一个对象,以动态地切换 class: <div v-bind:class="{ active: isActive }"></div> 上面的语法表示 active 这个 class 存在与否将取决于数据属性 isActive 的 truthiness. 你可以在对象中传入更多属性来动态

Vue.js 实战教程 V2.x(3)第一个Vue.js程序

假设你已了解关于 HTML.CSS 和 JavaScript 的知识. 3.1起步 创建一个 .html 文件,然后通过如下方式引入 Vue: <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> 3.2声明式渲染 Vue.js核心: <div id="app"> {{ message }} </div> var app = new V

Vue.js 实战教程 V2.x(12)表单输入绑定

12表单输入绑定 12.1基础用法 你可以用 v-model 指令在表单 <input>.<textarea> 及 <select> 元素上创建双向数据绑定.它会根据控件类型自动选取正确的方法来更新元素. 文本 <input v-model="message" placeholder="edit me"> <p>Message is: {{ message }}</p> 多行文本 <spa

Vue.js 实战教程 V2.x(7)计算属性和侦听器

7计算属性和侦听器 7.1计算属性 模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的. 在模板中放入太多的逻辑会让模板过重且难以维护. 所以,对于任何复杂逻辑,你都应当使用计算属性. 基础例子 <div id="example"> <p>Original message: "{{ message }}"</p> <p>Computed reversed message: "{{ reversedMe

Vue.js 实战教程 V2.x(2)Vue.js简介

2.1 Vue.js概述 Vue (读音 /vju?/,类似于 view) 是一套用于构建用户界面的渐进式框架. Vue.js官网的截图(2019年7月) 易用 会HTML.CSS.JavaScript就可以构建应用. 灵活 可以在一个库和一套完整框架之间自如伸缩. 高效 20kB运行大小,超快虚拟 DOM,最省心的优化 2.2与React对比 React官网的截图(2019年7月) 性能 React 和 Vue 都是非常快的. 优化 在 Vue 应用中,组件的依赖是在渲染过程中自动追踪的,所以

Vue.js 实战教程 V2.x(6)模板语法

Vue.js 使用了基于 HTML 的模板语法,允许开发者声明式地将 DOM 绑定至底层 Vue 实例的数据. 6.1插值 var obj = { msg: 'Hello Vue.js', rawHtml: '<span style="color: red">This should be red.</span>' } new Vue({ el: '#app', data: obj }) <div id="app"> ... <

Vue.js 实战教程 V2.x(1)前端发展史

1.1 Web 1.0时代 1989年,英国科学家蒂姆·伯纳斯-李在欧洲核子研究中心工作时发明了万维网(WWW). 第一个网站的截图(图片来源:CERN) 1990年,HTML(Hyper Text Markup Language)1.0发布. 1993年,CGI(Common Gateway Interface)诞生. 1994年,HTML 2.0发布. 1994年,Netscape公司成立,发布了第一款商业浏览器Navigator. 第一款商业浏览器的截图 1995年,Netscape推出了