Vue.js 教程 (5) : 显示数组
发布在Vue.js 中文入门2014年3月24日view:23074
在文章任何区域双击击即可给文章添加【评注】!浮到评注点上可以查看详情。

要显示数组,就要请出 v-repeat 指令了。v-repeat 会为其绑定的数组中的每一个对象建立一个子VM,该子 VM 的 $data 就是对应的数组对象。在 v-repeat 的元素上和其内部可以直接绑定该对象上的属性。同时每个子VM还有一个特殊的 $index 属性,代表其当前在数组中的位置。

<ul id="demo">
    <li v-repeat="todos">
        {{$index}} {{title}}
    </li>
</ul>
var todos = [
    { title: 'learn javascript' },
    { title: 'learn Vue.js' }
]

var demo = new Vue({
    el: '#demo',
    data: {
        todos: todos
    }
})

效果:http://jsfiddle.net/yyx990803/4WS3Z/

响应数组变化

Vue.js 通过在数组的畸变方法(mutating methods,即会改变数组自身的方法)中添加一个事件触发来侦听数组的变化。这些方法包括 push, pop, shift, unshift, splice, reversesort。要添加一项 todo,只需要在直接在数组里 push 一个对象:

todos.push({ title: 'learn everything!' })

扩展函数

同时 Vue.js 还给每一个被侦听的数组添加了 $set, 和 $remove 这两个扩展函数。由于在 ES5 中无法侦测数组直接对一个 index 赋值 (比如 arr[0] = value),需要用 arr.$set(0, value) 来保证 Vue.js 可以捕捉到事件;而 $remove 则只是一个用 splice 实现的便利函数,其参数可以是一个 index 也可以是数组中的一个对象:

// index
todos.$remove(0)

// object
var target = todos[0]
todos.$remove(target)

原始数据类型的数组

对于内容不是对象,而是原始数据类型的数组,比如 numbers: [1, 2, 3], 可以用 $value 来获得每个元素的值:

<ul>
    <li v-repeat="numbers">{{$value}}</li>
</ul>

元素标示符

v-repeat 内部,如果某个属性在当前 vm 实例上找不到,会自动 fallback 到父 vm 上去寻找。有时候父 vm 上可能存在同名属性,这种情况下我们可以给 v-repeat 加一个前置参数,作为循环对象的标示符:

<ul id="users">
    <!-- think of this as "for each user in users" -->
    <li v-repeat="user: users">
        {{user.name}} {{user.email}}
    </li>
</ul>

数组过滤器

Vue.js 0.10 新引入了两个方便的数组过滤器:filterByorderBy。顾名思义, filterBy 通过在每个对象上寻找一个给定的字符串来过滤数组元素,而 orderBy 则是根据比较每个对象上一个给定的属性来将数组排序。这两个过滤器都不对原始数组造成任何改动,只影响最后输出的视图结果。

filterBy 过滤器的第一个参数是要搜索的字符串变量。filterByorderBy 这两个过滤器的参数,如果带引号,会当做字符串直接拿来用;如果不带引号,则会先作为 vm 上的动态属性进行求值,然后以求值后的字符串作为值,同时如果该 vm 属性发生变化,会触发整个 v-repeat 表达式的刷新。

<input v-model="searchText">
<ul>
    <li v-repeat="users | filterBy searchText">{{name}}</li>
</ul>

上面这个例子是默认当只有一个参数时的情况。filterBy 会递归地对数组对象的每一个属性都做一次检测,只要有任意属性含有搜寻的字符串,该对象就会被显示。有时候我们可能需要限定只搜索特定属性,这时可以再加上 in ... 参数:

<input v-model="searchText">
<ul>
    <li v-repeat="users | filterBy searchText in 'name'">{{name}}</li>
</ul>

这样,就只会在每个对象的 name 属性里搜索了。

orderBy 更容易理解一些,其第二个参数代表是否要逆向排序。

<ul>
    <li v-repeat="users | sortBy field reverse">{{name}}</li>
</ul>

如果想要直接逆向排序,可以用 -1 这个特殊值:

<ul>
    <li v-repeat="users | sortBy 'name' -1">{{name}}</li>
</ul>
评论
发表评论
3年前
添加了一枚【评注】:双击标注,不明嚼栗
4年前
赞了此文章!
4年前

@qdsang 好问题啊,没有想到怎么做,用标识符也不行

4年前

@qdsang 好问题啊,没有想到怎么做,用标识符也不行

5年前

排序过滤器写错了,应该是 orderBy 而不是 sortBy。

5年前

@mr小虎锅 直接 this.data = newData 就可以,可以替换数组

5年前

在做分页的场景中,会对数组做整体替换,data.splice(0, data.length,[1,2,3]) 这样的写法不对,只能data.splice(0, data.length,1,2,3) 只能是常量 是不是我思路有问题

5年前

数组整体替换要怎么做

5年前

如果repeat嵌套了,内部的怎么获取外部的$index了?

6年前

@asins 多谢,这是近几个版本里的改动,这里忘了更新了…

6年前

code写错了,是{{$value}},少了个$

WRITTEN BY
尤小右
不会搞艺术的程序员不是好设计师
TA的新浪微博
PUBLISHED IN
Vue.js 中文入门

Vue.js 是一个轻巧、高性能、可组件化的MVVM库,同时拥有非常容易上手的API,让编写动态的UI界面变得轻松简单。本专栏是Vue.js的中文版入门教程。

我的收藏