侦听数组的变更方法(触发视图更新)

  1. 1. 变更方法
  2. 2. 替换数组
  3. 3. 其他
  4. 4. 显示过滤/排序后的结果
    1. 4.1. 1. 使用计算属性computed
      1. 4.1.1. 测试结果:
    2. 4.2. 2. 在计算属性不适用的情况下
      1. 4.2.1. 测试结果:

由于 JavaScript 的限制,Vue 不能检测数组和对象的变化, 比如:将数组的长度设置为0后,数组确实被清空了。但是Vue却不能检测到数组的变化,所以页面视图也不会响应。

为了解决这个问题,我们可以通过使用下列方法触发视图更新!

变更方法

这些方法包括:

push() 方法可向数组的末尾添加一个或多个元素,并返回新的长度。

pop() 方法用于删除并返回数组的最后一个元素。

shift() 方法用于把数组的第一个元素从其中删除,并返回第一个元素的值。

unshift() 方法可向数组的开头添加一个或更多元素,并返回新的长度。

splice() 方法向/从数组中添加/删除项目,然后返回被删除的项目。

sort() 方法用于对数组的元素进行排序。

reverse() 方法用于颠倒数组中元素的顺序。

你可以打开控制台,然后对items 数组尝试调用变更方法。比如 vm.items.push({ message: 'Baz' })

替换数组

​ 变更方法,顾名思义,会变更调用了这些方法的原始数组。相比之下,也有非变更方法,例如 :

filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。

concat() 方法用于连接两个或多个数组。

slice() 方法可从已有的数组中返回选定的元素。

它们不会变更原始数组,而总是返回一个新数组。当使用非变更方法时,可以用新数组替换旧数组:

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

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

其他

split() 方法用于把一个字符串分割成字符串数组。

显示过滤/排序后的结果

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

1. 使用计算属性computed

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<div id="app">
<li v-for="n in evenNumbers">{{ n }}</li>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
let vm = new Vue({
el: '#app',
data: {
numbers: [1, 2, 3, 4, 5]
},
computed: {
evenNumbers: function () {
return this.numbers.filter(function (number) {
return number % 2 === 0
})
}
}
});
</script>

测试结果:

2

4


注: 返回偶数数据

2. 在计算属性不适用的情况下

(例如,在嵌套 v-for 循环中) 你可以使用一个方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<div id="app">
<ul v-for="set in sets">
<li v-for="n in even(set)">{{ n }}</li>
</ul>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
let vm = new Vue({
el: '#app',
data: {
sets: [
[1, 2, 3, 4, 5],
[6, 7, 8, 9, 10]
]
},
methods: {
even: function (numbers) {
return numbers.filter(function (number) {
return number % 2 === 0
})
}
}
});
</script>


注: even(set) 调用vue里的方法,参数为外层循环遍历sets的某一层的迭代数据set。

测试结果:

  • 2

  • 4

  • 6

  • 8

  • 10