史上最詳細VUE2.0全套demo講解 基礎2(列表渲染)

混元霹靂手發表於2017-03-25

作者 :混元霹靂手-Ziksang

在基礎1釋出之後,我真心發現,根據api進一步分析,再結合工作中的實際demo給大家講解之後,大清早就收穫了平均一分種一個喜歡,這使我很欣慰,自己的努力沒有白費,我決心稱熱打鐵馬上出擊,打造基礎2,在基礎上的部分我將給大家講解列表渲染 v-for指令,在我自己認為這個是基礎篇的核心,為什麼我要放在第二部分講呢,因為我有很多demo例子都會基於v-for指令去講,這也是我們工作的核心,從後臺拿資料,再渲染資料,如果有對基礎1因為v-for指令看的不是很透徹的話,請看完這篇再回頭看看基礎1,還是那句話,支援我創作的請給一個大大的喜歡

v-for 列表渲染

  1. v-for array 陣列渲染

我們用v-for指令根據一組陣列的選項列表進行渲染。 v-for指令需要以item in items形式的特殊語法, items 是源資料陣列並且 item 是陣列元素迭代的別名。

應用場景:
通常情況下,進入一個活動要展示出所有參加活動的人員,裡面有姓名,年齡,報名時間等等,就先舉這三個列子,那後臺肯定會返回一個arraylist陣列集合,集合中每個元素肯定是一個物件,那我們如何去把這個陣列集合高效率,合理的渲染到頁面上,,再拿到使用者id去到下一個頁面查詢memberDetail祥情,用過jq的同學肯定知識很煩繁,一般肯定是用arttemplate這種模板引擎

<template>
     <div>
         <ul>
             <li v-for="(item,index) in memberList" @click="memberDetail(index)">
                 <span>{{item.custName}}</span>
                 <span>{{item.age}}</span>
                 <span>{{item.joinTime}}</span>
             </li>
         </ul>
     </div>
</template>

<script>
export default {
     created () {
         //就當看作是ajax在初始化進入的時候從後臺獲取的使用者列表資料
         this.memberList = [
            {custName : "ziksang1",age:20,joinTime : "2014-01-02",custId:1},
            {custName : "ziksang2",age:21,joinTime : "2014-01-03",custId:2},
            {custName : "ziksang3",age:22,joinTime : "2014-01-04",custId:3},
            {custName : "ziksang4",age:23,joinTime : "2014-01-05",custId:4},
         ]
     },
     data () {
         return {
             memberList : []
         }
     },
     methods : {
         memberDetail (index) {
             sessionStorage.custId = this.memberList[index].custId
         }
     }
}
</script>複製程式碼

我覺得這個demo太常用了,逐行分析
1.如果在template模板裡面用到了資料必須先在data選項裡先宣告賦值,我們先給memberList給予一個[]陣列
2.在created函式裡我們就當作模擬從後臺拿到的資料,然後賦值給data選項裡memberList,此時memberList就有後臺拿到的值了
3.(item,index) in memberList是vue自己封裝的一個語法結構
一.item代表集合中的每一個元素,此時每一個元素就是一個物件
二.index代表集合每一個元素的下標
三.memberList是所要迴圈的陣列
4.為什麼我們要把 (item,index) in memberList放在每一個迴圈dom上,那就是li標籤 只有在li迴圈體節點上和迴圈體所有子節點上拿到item這個物件裡面的所有屬性
5.@click="memberDetail(index)" 這裡用了一個點選方法,我們把index作為了方法的引數,目的是什麼,這個index代表每一個迴圈出來dom的下標,通過點選,我們可以拿到對應的使用者id可以說拿到每一個使用者的任意值,然後在methods我們進行操作,我們可以能過sessonStorage來存放,用來過度到下一個使用者祥情頁,來獲取所有使用者詳情,我們可以開啟谷歌瀏覽器,當我們用滑鼠點選的時候,可以發現sessionStorage裡的變化

整個流程是無論是開發任意中型專案必備的

2.template v-for

如同 v-if 模板,你也可以用帶有 v-for 的 <template> 標籤來渲染多個元素塊,迴圈塊區域

應用場景 :
當我們迴圈渲染時,我們如果有多個欠套不合理的關係下,一般情況下肯定是在最外層套一個div元素,這個我認為顯的不是很清楚,我們用template來代替渲染,不但能省去很dom節點,而且也能解決欠套不合理的情況

<template>
     <div>
         <template v-for="item in list">
              <p>{{item.content}}</p>
              <img :src="item.img" alt="">
              <p class="divider"></p>
         </template>
     </div>
</template>

<script>
export default {
     data () {
         return {
             list : [
                 {content : 'ziksang',img :'https://ss2.baidu.com/6ONYsjip0QIZ8tyhnq/it/u=1301074775,1382810875&fm=80&w=179&h=119&img.JPEG'},
                 {content : 'ziksang2',img :'https://ss0.baidu.com/6ONWsjip0QIZ8tyhnq/it/u=1312092207,1376369244&fm=80&w=179&h=119&img.JPEG'}
             ]
         }
     }
}
</script>
<style>
body,html{
    width:100%;
    height:100%
}
.divider{
    width:100%;
    height:1px;
    background:black;
}
</style>複製程式碼

如果我們不想多創節點,又不想讓p元素做為根節點,我們就可以用template來做渲染,在chorme開發者工具上,也能證實,最外層的的template會自動消失,不會創造出多餘的節點。

3. v-for Object 物件渲染

你也可以用 v-for 通過一個物件的屬性來迭代。

應用場景 :
就像第一個列子如果到了詳情頁,我們要展示一個使用者詳情,如果後端都給你排好序了,如何正確的方便展示出來,用最快,最便捷的方法那就是v-for 迭代物件,一般情況下展示一個使用者詳情,後臺肯定返回一個使用者物件給你

<template>
     <table>
         <template>
            <tr>
                <td v-for="(value,key,index) in memberDetail">{{key}}</td>
            </tr>
            <tr>
                <td v-for="(value,key,index) in memberDetail">{{value}}</td>
            </tr>
         </template>
     </table>
</template>

<script>
export default {
     created () {
        //比方說我們這裡拿到前面的custId傳給後臺拿到使用者資料
        this.memberDetail = {
                 name : 'ziksang',
                 age : 20,
                 address : "xxx省xxxx市",
                 tel : "15921898427"
             }
     },
     data () {
         return {
             memberDetail : {} 
         }
     }
}
</script>
<style>
body,html{
    width:100%;
    height:100%
}
.divider{
    width:100%;
    height:1px;
    background:black;
}
</style>複製程式碼

1.(value,key) in memberDetail
value代表屬性值
key 代表屬性,
index代表每個dom節點的下標索引
兩者都是一一對應的,通過第一個例子講解,我相信這個例子很簡單了

4. v-for 整數迭代

這個看看demo就可以了,我幾乎沒用過

<div>
  <span v-for="n in 10">{{ n }}</span>
</div>複製程式碼

4. v-for 和 元件

在自定義元件裡,你可以像任何普通元素一樣用 v-for 。

應用場景 :
比方拿掘金來說,每個使用者展現的文章列表中,每個使用者的文章可以做成一個統一元件,通過父元件來進行資料的傳遞,迴圈出所有人的文章,就形成了文章列表,而且可以在熱門,最新,或者專欄裡面複用,只需要通過資料傳遞,是一種相當好的模式

在components資料夾裡創一個myArticle檔案

<template>
    <div>
        <p>{{artList.name}}</p>
        <p>{{artList.startTime}}</p>
        <p>{{artList.content}}</p>
        <p>{{artList.good}}</p>
    </div>
</template>

<script>
export default {
    props : ['artList']
}
</script>複製程式碼

用props選項來接收父元件傳入的資料,渲染元件

App.vue檔案

<template>
     <div>
     <my-article v-for='item in artList' :art-list='item'></my-article>
     </div>
</template>

<script>
import myArticle from "./components/myArticle.vue"
export default {
    components : {
        myArticle
    },
    created () {
        //比方說我們是從後臺拿到的文章集合
        this.artList = [
            {name : 'ziksang1' , startTime : '1小時前' , content:'aaaaaaaaa',good : 1},
            {name : 'ziksang2' , startTime : '2小時前' , content:'bbbbbbbbb',good : 2},
            {name : 'ziksang3' , startTime : '3小時前' , content:'ccccccccc',good : 3},
            {name : 'ziksang4' , startTime : '4小時前' , content:'ddddddddd',good : 4}
        ]
     },
     data () {
         return {
             artList : [] 
         }
     }
}
</script>複製程式碼

這個需要逐行分析
1.首先們引入元件
2.v-for來迴圈元件
3.把每個文章的資料用 :art-list='item'傳給myArticle元件
如我們進行下拉載入和上拉重新整理的話,只要把取到的資料再次從新賦給子元件就可以了,而且我們還可以在各個頁面來重複複用這個元件,減少開發工作量

4. 陣列更新檢測

1.陣列變異

說的通俗一點,實是就是我們用Array.prototype裡提供的原型方法裡我們能直接改掉data選項裡的資料,觸發了檢視更新,那就是叫陣列變異方法
官方給大家列了只有那些方法能觸發檢視更新
1.push()
2.pop()
3.shift()
4.unshift()
5.splice()
6.sort()
7.reverse()

應用場景,我們比方說我們是絕境的後臺控制者,我們無聊看那個文章不爽,我們對文章進行操作,這個只是我瞎說玩玩的場景,就是用情景去模擬用法的場景

App.vue檔案

<template>
     <div>
     <my-article v-for='item in artList' :art-list='item'></my-article>
     <button @click='push'>新增文章</button>
     <button @click='pop'>尾部去除一篇文章</button>
     <button @click='unshift'>在頭部加入一條資料</button>
     <button @click='shift'>在頭部去除一條資料</button>
     <button @click='reverse'>把所有資料進行反轉</button>
     <button @click='clear'>清除所有資料</button>
     </div>
</template>

<script>
import myArticle from "./components/myArticle.vue"
export default {
    components : {
        myArticle
    },
    created () {
        //比方說我們這裡拿到前面的custId傳給後臺拿到使用者資料
        this.artList = [
            {name : 'ziksang1' , startTime : '1小時前' , content:'aaaaaaaaa',good : 1},
            {name : 'ziksang2' , startTime : '2小時前' , content:'bbbbbbbbb',good : 2},
            {name : 'ziksang3' , startTime : '3小時前' , content:'ccccccccc',good : 3},
            {name : 'ziksang4' , startTime : '4小時前' , content:'ddddddddd',good : 4}
        ]
     },
     data () {
         return {
             artList : [] 
         }
     },
     methods : {
          push () {
            this.artList.push({
                name : 'ziksang5' ,
                 startTime : '5小時前' ,
                  content:'eeeeeeeeee',
                  good : 5})
        },
        pop () {
            this.artList.pop()
        },
        shift () {
            this.artList.shift()
        },
        unshift () {
            this.artList.unshift({
                name : 'ziksang3',
                age : 40
            })
        },
        reverse () {
            this.artList.reverse()
        },
        clear () {
            this.artList = []
        }
     }
}
</script>複製程式碼

我們發現我們點這些按鈕的時候,myArticle的檢視同時跟著改變,這就是我們需要的效果就是變異方法根本的意思,能通過Array.prototype裡的原形方法改變data選項artList陣列觸發檢視改變的方法就是變異方法

2.陣列非變異

no-mutation methods(非變異方法),不能通過Array.prototype裡的原形方法改變data選項artList陣列觸發檢視改變的方法就是非變異方法,其餘的方法都是操作後,形成一個返回值,所有操作只是返回了一個新陣列,而不會觸發檢視更新
1.filter(), 2.concat(), 3.slice(), 4.map()

<template>
  <div>
      <ul>
         <li v-for = " (item,index) in list" v-text='`${item} - ${index} `'></li>
      </ul>
      <button @click="filter">陣列進行取餘過濾</button>
      <button @click="concat">陣列進行合併</button>
      <button @click="map">陣列印射</button>
      <button @click="slice">返回擷取後的陣列</button>
  </div>
</template>

<script>

export default {
    data () {    
        return {
            list : [ 1, 2, 3, 4],
            list2 : [ 7, 8, 9, 0 ]
        }
    },
    methods : {
        filter () {
            this.list = this.list.filter((item)=>{
                return item % 2
            })
        },
        concat () {
            //以上兩種方法都可以
            //1.第一種是es6的解構操作符
            //2.第二種是傳統的陣列合並
            this.list = [...this.list,...this.list2]
            //this.list = this.list.concat(this.list2)
        },
        map () {
            this.list = this.list.map(item =>{
                return `${item} map`
            })
        },
        slice () {
            this.list = this.list.slice(2)
        }
    }
}

</script>複製程式碼

那我們最終目的還是要通過方法來改變檢視更新,怎麼辦,很簡單,只要把形成的返回值再從新賦值給data選項裡的陣列就可以了,看api文件說起來很高深的樣子,但根本原理就是Array.prototye原型上方法導的鬼,我相信大家肯定很清楚了,上面我還在程式碼中對...解構新特性給大家演示了一個例子

4. 注意示項

官方提示:
由於 JavaScript 的限制, Vue 不能檢測以下變動的陣列:
當你利用索引直接設定一個項時,例如:vm.items[indexOfItem] = newValue
當你修改陣列的長度時,例如:vm.items.length = newLength

<template>
  <div>
      <ul>
         <li v-for = " (item,index) in list" v-text='`${item} - ${index} `'></li>
      </ul>
      <button @click="change3">改變陣列第2個值,改成0</button>
      <button @click="change4">改變陣列第2個值,改成5</button>
  </div>
</template>

<script>
import Vue from 'vue'
export default {
    data () {    
        return {
            list : [ 1, 2, 3, 4],
            list2 : [ 7, 8, 9, 0 ]
        }
    },
    methods : {
        //通過下標來改變整個陣列裡的值也是行不通的
        changeList () {
            this.list[2] = 3
        },
        //通過陣列長度改變改個陣列裡的值是行不通的
        changeList2 () {
            this.length = 1
        },
        //第一我們可以通過,vue.set實列方法來改變,但我們要在開頭再引一入下vue包
        // 1 第一個值代表需要改變的陣列
        // 2 第二個代表改變那一項
        // 3 第三個代表改成什麼值
        //樣式語法 Vue.set(example1.items, indexOfItem, newValue)
        change3 () {
            Vue.set(this.list,1,0)
        },
        //通過 Array.prototype.splice 陣列原型上的方法來改變整個陣列的長度或者內容
        //這個方法大家肯定常用,我就不細說了
        change4 () {
            this.list.splice(1,1,5)
        }
    }
}

</script>複製程式碼

這裡因為操作問題我就在程式碼中直接寫了註釋,更加能讓大家清楚的瞭解,如何通過那些方法改變陣列的長度,改變下標的某一個元素

5. 顯示過濾/排序效果

對於我的理解我就定義他叫副本過濾,在不改動data選項原陣列的同時,對新陣列進行改變,同時也不創造出多餘的資料值,那我們這裡就要用到一個基礎3所要講的計算屬性
應用場景 :
我在這裡做了一個小demo當原陣列裡面隨機改變值的同時,副本基於原陣列的建立出一個副本陣列跟著過濾的不同而改變
有兩個檢視:
1.第一個檢視,我們點選按紐改變1-10的隨機數
2.第二個檢視,隨著隨機數的改變來判斷是否為偶數是偶數的則過濾出來

<template>
  <div>
      <ul>
         <li v-for = " (item,index) in list" v-text='`${item} - ${index} `'></li>
      </ul>
      <ul>
         <li v-for = " (item,index) in filter" v-text='`${item} - ${index} `'></li>
      </ul>
      <button @click="randomList">隨機重置陣列的值</button>
  </div>
</template>

<script>
export default {
    data () {    
        return {
            list : [ 1, 2, 3, 4]
        }
    },
    //檢測計算 隨著原陣列用隨機數改變的同時,來篩選出不同的過濾結果,篩選結果是原陣列的裡面為偶數的值拼成一個新陣列
    //1.我們還可以用methods方法,但是不能一直監控
    computed : {
        filter () {
            return this.list.filter((item)=>{
                 return item % 2
            })
        }
    },
    methods : {
        //這裡就是隨著改變data原陣列裡的值
        randomList () {
            this.list = this.list.map(item => {
                return item+Math.round(Math.random()*9+1)
            })
        }
    }
}

</script>複製程式碼

隨著我們點選按鈕的同時,兩個檢視同時更新,本質上就是在data選項裡過濾出一個新陣列,同時這個新陣列不會影響到data選項裡的陣列,這個就叫做副本過濾,通過自己的想像可以做出很多不同的demo例子

講到這個裡所有v-for 列表渲染已經講的我個人認為非常透徹了,如果你動手去把這些程式碼貼進vue-cli中理解一下,再動手自己敲兩個demo,我想你的專案開發速度絕對能提升一倍,最後別望了點贊哦,還是那句話我的更新速度,取決於你們對我的認可,謝謝

掘金史上最詳細VUE2.0全套demo講解(基礎篇3) ==> 計算屬性

渣渣前端開發工程師,喜歡鑽研,熱愛分享和講解教學, 微信 zzx1994428 QQ494755899

支援我繼續創作和感到有收穫的話,請向我打賞點吧

史上最詳細VUE2.0全套demo講解 基礎2(列表渲染)

如果轉載請標註出自@混元霹靂手ziksang

相關文章