1. 程式人生 > >說說 Vue.js 中的 v-for 列表渲染指令

說說 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):