7. 列表渲染

v-for 指令 — 数组

  1. v-for 指令基于一个数组来渲染一个列表
  2. 使用 item in items(item, index) in items形式的特殊语法
  3. items是源数据数组, item 是被迭代的数组元素的别名
  • {{ parentMessage }} - {{ index }} - {{ item.message }}
var example2 = new Vue({
  el: '#example-2',
  data: {
    parentMessage: 'Parent', // v-for 可直接访问
    items: [
      { message: 'Foo' }, //数组内对象为被迭代的item
      { message: 'Bar' }
    ]
  }
})
  • v-for块中,可以访问所有父作用域的属性

  • 可用 of 替代in 作为分隔符

维护状态-key

  1. 当 Vue 正在更新使用 v-for 渲染的元素列表时,默认使用“就地更新”的策略
  2. 只适用于不依赖子组件状态或临时 DOM 状态 (例如:表单输入值) 的列表渲染输出
  3. 为每项提供一个唯一 key 属性,便于跟踪每个节点的身份,从而重用和重新排序现有元素
  • 不要使用对象或数组之类的非基本类型值作为 v-forkey

数组更新检测

变异方法 (mutation method)

  1. Vue 将被侦听的数组的变异方法进行了包裹,变异方法将会触发视图更新
  2. 改变调用了变异方法的原始数组
  • push()——接收任意数量的参数,把逐个添加到数组末尾,并返回修改后数组的长度
  • pop()——从数组末尾移除后一项,减少数组的 length 值,返回移除的项
  • shift()——移除数组中的第一个项并返回该项,同时将数组长度减 1
  • unshift()——能在数组前端添加任意个项并返回新数组的长度
  • splice()——向数组的中部插入项(删除项的起始位置、删除的项数、插入任意数量的项)
  • sort()——按升序排列数组项,可以接收一个比较函数作为参 数
  • reverse()——反转数组项的顺序

替换数组

  1. 不会改变原始数组,而总是返回一个新数组
  2. 当使用非变异方法时,可以用新数组替换旧数组
example1.items = example1.items.filter(function (item) {
  return item.message.match(/Foo/)
})
  • filter()
  • concat()
  • slice()

注意事项

由于 JavaScript 的限制,Vue 不能检测以下数组的变动,在界面为非响应式

  1. 利用索引直接设置一个数组项时

    vm.items[2] = 'newValue'
    
  2. 修改数组的长度时

    vm.items.length = 3
    

解决问题

vm.items[indexOfItem] = newValue

方式一:

// Vue.set
Vue.set(vm.items, indexOfItem, newValue)
vm.$set(vm.items, indexOfItem, newValue)  //vm.$set 实例方法
Vue.set(items, 2, '响应式新值')

方式二:

// Array.prototype.splice
vm.items.splice(indexOfItem, 1, newValue)
vm.items.splice(2, 1, '响应式新值')

vm.items.length = newLength

vm.items.splice(newLength)
vm.items.splice(3)

v-for 指令 — 对象

  1. v-for 来遍历一个对象的属性
  2. 使用 value in object(value, name, index) in object形式的特殊语法
键名-{{ value}} 键值-{{ name }} 索引-{{ index}}
new Vue({
  el: '#v-for-object',
  data: {
    object: {
      title: 'How to do lists in Vue',
      author: 'Jane Doe',
      publishedAt: '2019-10-25'
    }
  }
})
  • 在遍历对象时,会按 Object.keys() 的结果遍历

对象变更检测

注意事项

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

  1. 对于已经创建的实例,Vue 不允许动态添加根级别的响应式属性

解决方法

Vue.set(object, propertyName, value) 方法向嵌套对象添加响应式属性

添加单个属性

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

添加多个属性

vm.userProfile = Object.assign({}, vm.userProfile, {
  age: 27,
  favoriteColor: 'Vue Green'
})

显示过滤/排序后的结果

  1. 显示一个数组经过过滤或排序后的版本,而不实际改变或重置原始数据

    计算属性

  2. {{ n }}
  3. data: {
     number: [ 1, 2, 3, 4, 5 ]
    },
    computed: {
     evenNumbers: function() {
         return this.number.fliter( function(number) {
             return number % 2 === 0
         })
     }
    }
    

    方法

  4. {{ n }}
  5. data: {
      numbers: [ 1, 2, 3, 4, 5 ]
    },
    methods: {
      even: function (numbers) {
        return numbers.filter(function (number) {
          return number % 2 === 0
        })
      }
    }