Vue.js的条件v-if和列表循环v-for

条件

v-if 、v-else、v-show、还可以使用template

<div v-if="ok">ok</div>
<div v-else>No</div>
<div v-show="ok">ok</div>
<template v-if="ok">
<strong>测试template</strong>
</template>
<template v-else>
<strong>no template</strong>
</template>

演示

列表循环v-for

循环数组

<ul>
<li v-for=”todo in todos”>{{todo.text}}</li>
</ul>

多级列表,第二个参数提供当前项的索引、template模板

<div v-for="items in list">
<template v-for="(item, index) in items">{{index}} - {{item.message}}<br/></template>
</div>

对象迭代:

一个参数作为值

<div v-for="value in object">
{{value}}
</div>

第二个参数作为键名

<div v-for="(value,key) in object">
{{key}} - {{value}}
</div>

第三个参数作为当前项的索引

<div v-for="(value,key,index) in object">
{{index}} - {{key}} : {{value}}
</div>

组件 和 v-for

循环数组数据到组件中,使用props,可以把值和当前索引赋值给组件。

<my-component
v-for="(item, index) in items"
v-bind:item="item"
v-bind:index="index">
</my-component>

或者下面这种加了某些有语义标签,里面有一个is=”组件名”

<li
is="todo-item"
v-for="(todo, index) in todos"
v-bind:item="todo"
v-on:remove="todos.splice(index, 1)"
></li>

下面是一个完整示例:

<div id="todo-list-example">
	<input
	v-model="newTodoText"
	v-on:keyup.enter="addNewTodo"
	placeholder="Add a todo"
	>
	<ul>
		<li
		is="todo-item"
		v-for="(todo, index) in todos"
		v-bind:item="todo"
		v-on:remove="todos.splice(index, 1)"
		></li>
	</ul>
</div>
Vue.component('todo-item', {
	template: '\
	<li>\
	{{ item }}\
		<button v-on:click="$emit(\'remove\')">X</button>\
	</li>\
	',
	props: ['item']
})
new Vue({
	el: '#todo-list-example',
	data: {
		newTodoText: '',
		todos: [
		'Do the dishes',
		'Take out the trash',
		'Mow the lawn'
		]
	},
	methods: {
		addNewTodo: function () {
			this.todos.push(this.newTodoText)
			this.newTodoText = ''
		}
	}
})

使用props将数组循环的索引项和值赋值给当前组件

发现一个细节,就是组件模板template分行要加一个\,另外双引号里面有分号也要加一个\.

使用当前执行函数,$emit(\’remove\’);remove是绑定在DOM中的函数。

key

为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 key属性。理想的 key 值是每项都有唯一 id。这个特殊的属性相当于 Vue 1.x 的 track-by ,但它的工作方式类似于一个属性,所以你需要用 v-bind 来绑定动态值(在这里使用简写):

<div v-for="item in items" :key="item.id">
<!-- 内容 -->
</div>

建议尽可能使用 v-for 来提供 key ,除非迭代 DOM 内容足够简单,或者你是故意要依赖于默认行为来获得性能提升。

因为它是 Vue 识别节点的一个通用机制, key 并不特别与 v-for 关联,key 还具有其他用途,我们将在后面的指南中看到其他用途。

数组更新检测

Vue 包含一组观察数组的变异方法,所以它们也将会触发视图更新。这些方法如下:

  • push()
  • pop()
  • shift()
  • unshift()
  • splice()
  • sort()
  • reverse()

你打开控制台,然后用前面例子的 items 数组调用突变方法:example1.items.push({ message: 'Baz' })

重塑数组

变异方法(mutation method),顾名思义,会改变被这些方法调用的原始数组。相比之下,也有非变异(non-mutating method)方法,例如: filter(), concat(), slice() 。这些不会改变原始数组,但总是返回一个新数组。当使用用非变异方法时,可以用新数组替换旧数组:

example1.items = example1.items.filter(function (item) {
return item.message.match(/Foo/)
})

你可能认为这将导致 Vue 丢弃现有 DOM 并重新渲染整个列表。幸运的是,事实并非如此。 Vue 实现了一些智能启发式方法来最大化 DOM 元素重用,所以用一个含有相同元素的数组去替换原来的数组是非常高效的操作。

注意事项

由于 JavaScript 的限制, Vue 不能检测以下变动的数组:

  1. 当你直接设置一个项的索引时,例如: vm.items[indexOfItem] = newValue
  2. 当你修改数组的长度时,例如: vm.items.length = newLength

为了避免第一种情况,以下两种方式将达到像 vm.items[indexOfItem] = newValue 的效果, 同时也将触发状态更新:

// Vue.set
Vue.set(example1.items, indexOfItem, newValue)
// Array.prototype.splice`
example1.items.splice(indexOfItem, 1, newValue)

避免第二种情况,使用 splice

example1.items.splice(newLength)

显示过滤/排序结果

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

例如:

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

或者,您也可以使用在计算属性是不可行的 method 方法 (例如,在嵌套 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
})
}
}

演示


关注我

我的微信公众号:前端开发博客,在后台回复以下关键字可以获取资源。

  • 回复「小抄」,领取Vue、JavaScript 和 WebComponent 小抄 PDF
  • 回复「Vue脑图」获取 Vue 相关脑图
  • 回复「思维图」获取 JavaScript 相关思维图
  • 回复「简历」获取简历制作建议
  • 回复「简历模板」获取精选的简历模板
  • 回复「加群」进入500人前端精英群
  • 回复「电子书」下载我整理的大量前端资源,含面试、Vue实战项目、CSS和JavaScript电子书等。
  • 回复「知识点」下载高清JavaScript知识点图谱

每日分享有用的前端开发知识,加我微信:caibaojian89 交流