vue条件渲染和列表渲染

admin
admin 2019年04月16日
  • 在其它设备中阅读本文章

条件渲染

v-if 指令用于条件性地渲染一块内容。这块内容只会在指令的表达式返回 truthy 值的时候被渲染。

<h1 v-if="awesome">Vue is awesome!</h1>

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

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

你可以使用 v-else 指令来表示 v-if 的“else 块”:v-else 元素必须紧跟在带 v-if 或者 v-else-if 的元素的后面,否则它将不会被识别。

<div v-if="Math.random() > 0.5">
  Now you see me
</div>
<div v-else>
  Now you don't
</div>

注意:
Vue 会尽可能高效地渲染元素,通常会复用已有元素而不是从头开始渲染。这么做除了使 Vue 变得非常快之外,还有其它一些好处。例如,如果你允许用户在不同的登录方式之间切换:

<template v-if="loginType === 'username'">
  <label>Username</label>
  <input placeholder="Enter your username">
</template>
<template v-else>
  <label>Email</label>
  <input placeholder="Enter your email address">
</template>

那么在上面的代码中切换 loginType 将不会清除用户已经输入的内容。因为两个模板使用了相同的元素,\<input\> 不会被替换掉——仅仅是替换了它的 placeholder, 如果想要阻止这种行为,只需添加一个具有唯一值的 key 属性即可。

<input placeholder="Enter your username" key="username-input">

另一个用于根据条件展示元素的选项是 v-show 指令。用法大致一样:

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

不同的是带有 v-show 的元素始终会被渲染并保留在 DOM 中。v-show 只是简单地切换元素的 CSS 属性 display。
注意
v-show 不支持 \<template\> 元素,也不支持 v -else

v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。

列表渲染

我们用 v-for 指令根据一组数组的选项列表进行渲染。v-for 指令需要使用 item in items 形式的特殊语法,items 是源数据数组并且 item 是数组元素迭代的别名。

<ul id="example-1">
  <li v-for="item in items">
    {{ item.message }}
  </li>
</ul>

data: {
  items: [
    { message: 'Foo' },
    { message: 'Bar' }
  ]
}

结果:

Foo
Bar

你也可以用 v-for 通过一个对象的属性来迭代。你也可以提供第二个的参数为键名, 第三个参数为索引:

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

data: {
  object: {
    firstName: 'John',
    lastName: 'Doe',
    age: 30
  }
}

v-for 也可以取整数。在这种情况下,它将重复多次模板。

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

结果:

1 2 3 4 5

类似于 v-if,你也可以利用带有 v-for 的 \<template\> 渲染多个元素。比如:

<ul>
  <template v-for="item in items">
    <li>{{ item.msg }}</li>
    <li class="divider" role="presentation"></li>
  </template>
</ul>

注意:
由于 JavaScript 的限制,Vue 不能检测以下变动的数组:
当你利用索引直接设置一个项时,例如:vm.items[indexOfItem] = newValue
当你修改数组的长度时,例如:vm.items.length = newLength

var vm = new Vue({
  data: {
    items: ['a', 'b', 'c']
  }
})
vm.items[1] = 'x' // 不是响应性的
vm.items.length = 2 // 不是响应性的

为了解决第一类问题,以下两种方式都可以实现和 vm.items[indexOfItem] = newValue 相同的效果,同时也将触发状态更新:

// Vue.set
Vue.set(vm.items, indexOfItem, newValue)
// Array.prototype.splice
vm.items.splice(indexOfItem, 1, newValue)
//你也可以使用 vm.$set 实例方法,该方法是全局方法 Vue.set 的一个别名:

vm.$set(vm.items, indexOfItem, newValue)

为了解决第二类问题,你可以使用 splice:

vm.items.splice(newLength)