Vue列表渲染【七】

列表渲染

v-for

v-for 指令基于一个数组来渲染一个列表。v-for 指令需要使用 item in items 形式的特殊语法,其中 items 是源数据数组,而 item 则是被迭代的数组元素的别名

<div id="app">
      <ul>
        <li v-for="(item, index) in items" :key="index">
          {{parent}}-{{index}}-{{item.message}}
        </li>
      </ul>
    </div>

    <script>
      let vm = new Vue({
        el: '#app',
        data: function () {
          return {
            parent: 'Parent',
            items: [{ message: 'foo' }, { message: 'bar' }, { message: 'you' }]
          }
        }
      })
    </script>

也可以用of来代替in

v-for中使用对象

<div id="app">
      <p v-for="(item, name,index) in object" :key="index">
        {{index}}.{{name}}:{{item}}
      </p>
    </div>

    <script>
      let vm = new Vue({
        el: '#app',
        data: function () {
          return {
            object: {
              name: 'dabc',
              age: 13,
              sex: 'boy'
            }
          }
        }
      })
    </script>

维护状态

当 Vue 正在更新使用 v-for 渲染的元素列表时,它默认使用“就地更新”的策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序,而是就地更新每个元素,并且确保它们在每个索引位置正确渲染。

只适用于不依赖子组件状态或临时 DOM 状态 (例如:表单输入值) 的列表渲染输出

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

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

数组更新检测

变更方法

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

  • 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 丢弃现有 DOM 并重新渲染整个列表。幸运的是,事实并非如此。Vue 为了使得 DOM 元素得到最大范围的重用而实现了一些智能的启发式方法,所以用一个含有相同元素的数组去替换原来的数组是非常高效的操作。

注意事项

由于 JavaScript 的限制,Vue 不能检测数组和对象的变化。

显示过滤/排序后的结果

有两种方法实现:计算属性和嵌套v-for的methods方法

计算属性
<div id="app">
      <li v-for="(item, index) in evenNumbers" :key="index">
        {{item}}
      </li>
    </div>

    <script>
      let vm = new Vue({
        el: '#app',
        data: function () {
          return {
            numbers: [1, 2, 3, 4, 5]
          }
        },
        computed: {
          evenNumbers: function () {
            return this.numbers.filter(function (number) {
              return number % 2 === 0
            })
          }
        }
      })
    </script>
methods方法
<div id="app">
      <ul v-for="(set, index) in numbers" :key="index">
        <li v-for="(n, index) in evenNumber(set)" :key="index">{{n}}</li>
      </ul>
    </div>

    <script>
      let vm = new Vue({
        el: '#app',
        data: function () {
          return {
            numbers: [[1, 2, 3, 4, 5]]
          }
        },
        methods: {
          evenNumber: function (numbers) {
            return numbers.filter(function (number) {
              return number % 2 === 0
            })
          }
        }
      })
    </script>

v-for中使用值范围

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

结果为:12345678910

<template>上使用v-for

类似于v-if

<div id="app">
      <template v-for="(item, index) in items" :key="index">
        <h1>{{item.message}}</h1>
        <h2>我是分隔线</h2>
        <hr />
      </template>
    </div>

    <script>
      let vm = new Vue({
        el: '#app',
        data: function () {
          return {
            items: [{ message: 'foo' }, { message: 'bar' }, { message: 'you' }]
          }
        }
      })
    </script>

v-forv-if

注意我们推荐在同一元素上使用 v-ifv-for

  • 当它们处于同一节点,v-for 的优先级比 v-if 更高,这意味着 v-if 将分别重复运行于每个 v-for 循环中。当你只想为部分项渲染节点时,这种优先级的机制会十分有用
<div id="app">
      <table border="1" cellspacing="0">
        <tr
          v-for="(item, index) in items"
          :key="index"
          v-if="item.sex==='girl'"
        >
          <td>{{item.name}}</td>
          <td>{{item.age}}</td>
          <td>{{item.sex}}</td>
        </tr>
      </table>
    </div>

    <script>
      let vm = new Vue({
        el: '#app',
        data: function () {
          return {
            items: {
              alice: {
                name: 'alice',
                age: 13,
                sex: 'girl'
              },
              bob: {
                name: 'bob',
                age: 14,
                sex: 'boy'
              },
              mary: {
                name: 'mary',
                age: 15,
                sex: 'girl'
              }
            }
          }
        }
      })
    </script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值