说说 Vue.js 中的 v-for 列表渲染指令

1 基本用法

当遍历一个数组或枚举一个对象进行迭代循环展示时,就会用到列表渲染指令 v-for。 它的表达式需要结合 in 来使用,类似 item in items 的形式。

1.1 遍历数组

html:

<div id="app">
    <ul>
        <li v-for="n in news">{{n.title}}</li>
    </ul>
</div>

js:

<script>
    var app = new Vue({
        el: '#app',
        data: {
            news: [
                {title: '被智能手机绑架的i世代 爱熬夜、拒绝恋爱、不考驾照'},
                {title: '黑莓宣布14亿美元收购网络安全公司Cylance'},
                {title: '如何看待阿里巴巴开酒店这件事?'}
            ]
        }
    });
</script>

效果:

在 v-for 指令的表达式中, news 是 data 内定义的数据, n 是当前数组元素的别名。

列表渲染指令的表达式也支持使用 of 作为分隔符。

html:

<li v-for="n of news">{{n.title}}</li>

v-for 表达式支持当前项索引参数,索引从 0 开始,它是可选的 。

html:

 <li v-for="(n,index) of news">{{index}} - {{n.title}}</li>

效果:


也可以使用内置标签 <template>,渲染多个元素。

html:

<div id="app2">
    <dl>
        <template v-for="n in news">
            <dt>{{n.title}}</dt>
            <dd>{{n.content}}</dd>
        </template>
    </dl>
</div>

js:

var app2 = new Vue({
    el: '#app2',
    data: {
        news: [
            {title: '科技',content:'智能手机是我们生活的好帮手... ...'},
            {title: '互联网',content:'黑莓公司周五宣布... ...'},
            {title: '社会',content:'阿里实体酒店“FlyZoo Hotel”将开业... ...'}
        ]
    }
});

效果:

1.2 遍历对象属性

我们也可以使用 v-for 列表渲染指令来遍历对象属性。

html:

<div id="app3">
    <li v-for="val in account">{{val}}</li>
</div>

js:

var app3 = new Vue({
    el: '#app3',
    data: {
        account: {
            name: 'deniro',
            messageCount: 100
        }
    }
});

效果:

遍历对象属性,可以带上两个可选参数,它们就是对象的属性名和索引:

html:

<li v-for="(val,name,index) in account">{{index}} - {{name}} : {{val}}</li>

1.3 迭代整数

html:

<div id="app4">
    <ul>
        <li v-for="i in 5">{{i}}</li>
    </ul>
</div>

js:

var app4 = new Vue({
    el: '#app4'
});

效果:


2 更新数组

Vue.js 的核心是数据与视图的双向绑定。因此当我们修改数组时, Vue.js 就会检测到数据了变化,所以用 v-for 渲染的视图也会更新 。使用以下方法修改数组时,就会触发视图更新:

  • push()
  • shift()
  • unshift()
  • splice()
  • sort()
  • reverse()

这些方法会改变原数组,所以又称为变异方法。

我们使用 push() 为 app 对象新增一个新闻标题:

js:

app.news.push({
    title:'沃尔玛将超过苹果成美国第三大在线零售商'
});

效果:


也有一些非变异方法,它们不会改变原数组,只会返回新数组:

  • filter()
  • concat()
  • slice()

我们在使用这些方法时,可以通过设置新数组的方式来更新视图。

js:

//非变异方法更新数组
    app.news = app.news.filter(function (item) {
        return item.title.match(/阿里巴巴/);
    });

效果:

这个示例中,我们使用 filter 函数,把新闻标题中含有“阿里巴巴”字样的新闻过滤出来。

Vue.js 在检测数组变化时,会最大化地复用 DOM 元素。 替换的数组,如果含有相同元素的项并不会被重新渲染,所以不用担心性能问题。

注意:通过以下方法来改变数组, Vue.js 是无法检测的,所以不会更新视图:

  1. 通过索引来设置项,比如 app.new[1]={...}
  2. 修改数组长度,比如 app.new.length=1

我们可以使用 Vue.js 内置的 set 方法(可指定索引)来更新数组:

//通过 set 的设置索引方式来更新数组
Vue.set(app.news,1,{
    title: '大数据之下的锦鲤:为什么你的微博总抽不到奖'
});

效果:


也可以使用 splice 指定索引来更新数组:

//通过 splice 的设置索引方式来更新数组
app.news.splice(1, 0, {
    title: '南京现“刷脸支付”超市 网友:素颜去结账机器能识'
});

至于第二个问题,同样可以通过 splice 来实现:

//通过 splice 来删除数组元素
app.news.splice(1);

以上示例 demo

3 过滤或排序

其实,之前已经有一个示例用到了 filter() 过滤方法。如果我们不想改变原数组,只想返回过滤或排序后数组副本,这时可以使用计算属性来实现。

html:

<div id="app">
    <h3>过滤出带“美元”的标题</h3>
    <ul>
        <li v-for="(n,index) in filterNews">{{index}} - {{n.title}}</li>
    </ul>
    <h3>按照标题长度,由短到长排序</h3>
    <ul>
        <li v-for="(n,index) in sortNews">{{index}} - {{n.title}}</li>
    </ul>
</div>

js:

<script>
    var app = new Vue({
        el: '#app',
        data: {
            news: [
                {title: '被智能手机绑架的i世代 爱熬夜、拒绝恋爱、不考驾照'},
                {title: '黑莓宣布14亿美元收购网络安全公司Cylance'},
                {title: '如何看待XXX开酒店赚美元这件事?'}
            ]
        },
        computed: {
            //过滤出带“美元”的标题
            filterNews: function () {
                return this.news.filter(function (item) {
                    return item.title.match(/美元/);
                })
            },
            //按照标题长度,由短到长排序
            sortNews: function () {
                return this.news.sort(function (val1, val2) {
                    if(val1.title.length < val2.title.length){
                        return -1;
                    }
                })
            }
        }
    });
</script>

效果(demo):

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,711评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,079评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,194评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,089评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,197评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,306评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,338评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,119评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,541评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,846评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,014评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,694评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,322评论 3 318
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,026评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,257评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,863评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,895评论 2 351

推荐阅读更多精彩内容

  • Vue 实例 属性和方法 每个 Vue 实例都会代理其 data 对象里所有的属性:var data = { a:...
    云之外阅读 2,204评论 0 6
  • 主要还是自己看的,所有内容来自官方文档。 介绍 Vue.js 是什么 Vue (读音 /vjuː/,类似于 vie...
    Leonzai阅读 3,341评论 0 25
  • 我拾起一片落叶 细数它的纹理 我看到了诗行 是大树写给大地的情书 写满沃土十年如一日的守护 写满春夏秋冬爱的语录 ...
    王二痞子阅读 1,143评论 17 41