Vue.js入门学习(四)条件/列表渲染

条件渲染

v-if:

在字符串模板中,我们需要写这样一个条件块:

{{#if ok}}
  <h1>Yes</h1>
{{/if}}
但是在Vue.js中,我们使用 v-if 就可以实现上述同样的功能:
<h1 v-if="ok">Yes</h1>
也可以用 v-else 添加一个 "else" 块:
<h1 v-if="ok">Yes</h1>
<h1 v-else>No</h1>

template v-if:

因为 v-if 是一个指令,需要将它添加到一个元素上。但是如果我们想切换多个元素呢?此时我们可以把一个 <template> 元素当做包装元素,并在上面使用 v-if,最终的渲染结果不会包含它。

<template v-if="ok">
  <h1>Title</h1>
  <p>Paragraph 1</p>
  <p>Paragraph 2</p>
</template>
v-show:

这也是一个根据条件展示的元素 v-show 指令。

<h1 v-show="ok ">Hello!</h1>

不同的是有 v-show 的元素会始终渲染并保持在 DOM 中。v-show 是简单的切换元素的 CSS 属性 display

注意 v-show 不支持 <template> 语法。

v-else:

可以用 v-else 指令给 v-if 或 v-show 添加一个 "else 块":

<div v-if="Math.random() > 0.5">
  Sorry
</div>
<div v-else>
  Not sorry
</div>

注意: v-else 元素必须立即跟在 v-if 或 v-show 元素的后面——否则它不能被识别。


v-if    VS   v-show:

在切换 v-if 块时,Vue.js 有一个局部编译/卸载过程,因为 v-if 之中的模板也可能包括数据绑定或子组件。v-if 是真实的条件渲染,因为它会确保条件块在切换当中合适地销毁与重建条件块内的事件监听器和子组件。

v-if 也是惰性:如果在初始渲染时条件为假,则什么也不做——在条件第一次变为真时才开始局部编译(编译会被缓存起来)。

相比之下,v-show 简单得多——元素始终被编译并保留,只是简单地基于 CSS 切换。

一般来说,v-if 有更高的切换消耗而 v-show 有更高的初始渲染消耗。因此,如果需要频繁切换 v-show 较好,如果在运行时条件不大可能改变 v-if 较好。


列表渲染

v-for

可以使用 v-for 指令基于一个数组渲染一个列表。这个指令使用特殊的语法,形式为 item in itemsitems 是数据数组,item 是当前数组元素的别名。例如:

<ul id="example-1" class="demo">
  <li v-for="item in items">
    {{item.message}}
  </li>
</ul>
<script>
var example1 = new Vue({
  el: '#example-1',
  data: {
    items: [
      { message: 'Foo' },
      { message: 'Bar' }
    ]
  },
  watch: {
    items: function () {
      smoothScroll.animateScroll(null, '#example-1')
    }
  }
})
</script>

在 v-for 块内我们能完全访问父组件作用域内的属性,另有一个特殊变量 $index,是当前数组元素的索引。

注意Vue2.x的更新,已经移除$index,且在v-for中显示定义为 v-for="(item , index) in items" 。

template v-for

类似于 template v-if,也可以将 v-for 用在 <template> 标签上,以渲染一个包含多个元素的块。


数组变动检测

变异方法

Vue.js 包装了被观察数组的变异方法,故它们能触发视图更新。被包装的方法有:

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

你可以打开浏览器的控制台,用这些方法修改上例的 items 数组。例如:example1.items.push({ message: 'Baz' })

替换数组

变异方法,如名字所示,修改了原始数组。相比之下,也有非变异方法,如 filter()concat() 和 slice(),不会修改原始数组而是返回一个新数组。在使用非变异方法时,可以直接用新数组替换旧数组:

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

* Vue.js 实现了一些启发算法,以最大化复用 DOM 元素,因而用另一个数组替换数组是一个非常高效的操作。

track-by

有时需要用全新对象(例如通过 API 调用创建的对象)替换数组。因为 v-for 默认通过数据对象的特征来决定对已有作用域和 DOM 元素的复用程度,这可能导致重新渲染整个列表。但是,如果每个对象都有一个唯一 ID 的属性,便可以使用 track-by 特性给 Vue.js 一个提示,Vue.js 因而能尽可能地复用已有实例。

track-by $index

如果没有唯一的键供追踪,可以使用 track-by="$index",它强制让 v-for 进入原位更新模式:片断不会被移动,而是简单地以对应索引的新值刷新。这种模式也能处理数据数组中重复的值。<一般小心使用,效率高但是代价大>

问题

因为 JavaScript 的限制,Vue.js 不能检测到下面数组变化:

  1. 直接用索引设置元素,如 vm.items[0] = {}
  2. 修改数据的长度,如 vm.items.length = 0

为了解决问题 (1),Vue.js 扩展了观察数组,为它添加了一个 $set() 方法:

// 与 `example1.items[0] = ...` 相同,但是能触发视图更新
example1.items.$set(0, { childMsg: 'Changed!'})

至于问题 (2),只需用一个空数组替换 items

除了 $set(), Vue.js 也为观察数组添加了 $remove() 方法,用于从目标数组中查找并删除元素,在内部它调用 splice() 。因此,不必这样:

var index = this.items.indexOf(item)
if (index !== -1) {
  this.items.splice(index, 1)
}

只用这样:

this.items.$remove(item)

对象 v-for

也可以使用 v-for 遍历对象。除了 $index 之外,作用域内还可以访问另外一个特殊变量 $key

<ul id="repeat-object" class="demo">
  <li v-for="value in object">
    {{ $key }} : {{ value }}
  </li>
</ul>
<script>
new Vue({
  el: '#repeat-object',
  data: {
    object: {
      FirstName: 'John',
      LastName: 'Doe',
      Age: 30
    }
  }
})
</script>

值域 v-for

v-for 也可以接收一个整数,此时它将重复模板数次。

<div id="range" class="demo">
  <span v-for="n in 10">{{ n }} </span>
</div>
<script>
new Vue({ el: '#range' })
</script>

显示过滤/排序的结果

有时我们想显示过滤/排序过的数组,同时不实际修改或重置原始数据。有两个办法:

  1. 创建一个计算属性,返回过滤/排序过的数组;
  2. 使用内置的过滤器 filterBy 和 orderBy

计算属性有更好的控制力,也更灵活,因为它是全功能 JavaScript。但是通常过滤器更方便。



猜你喜欢

转载自blog.csdn.net/chenjuan1993/article/details/81003677