###### tags:`Vue` # 3.Vue v-for與其使用細節 1. 物件與陣列差別 3. 反轉陣列 4. 過濾資料方式(filter只能用於array陣列) 5. 在javascript上能運作,但在vue無法直接運作(1) 6. 在javascript上能運作,但在vue無法直接運作(2) 7. 使用v-for在畫面產生純數字的迴圈 8. 搭配Template < tr>表格輸出 9. v-for 與 v-if一起搭配使用 10. v-for 與 元件 ### 1物件與陣列的差別 #### 1-1物件 [資料來源](https://ithelp.ithome.com.tw/articles/10190962) <p > 物件為多個零件集合,含多種屬性,甚至是一個函數.可以是瀏覽器預先定義好的,也可以是由自己定義物件的屬性與內容。 </p> <p style="color:red">物件包在<b>{ }大括號</b>裡面</p> <p style="color:red">物件裡面可以有<span style="font-style: italic;">陣列</span></p> 舉例: * 這個學校名字是中正國小,三年丁班(D)有45個人,分別來至大安里,幸福里,健康里,成功里四個不同區的住戶小朋友 * 取出值方法為 var school ={ dist:['大安里','幸福里','健康里','成功里'] } * 三年丁班(A)有28個人,三年丁班(B)有29個人,三年丁班(C)有37個人,三年丁班(D)有45個人 * 寫成物件為下面 ``` var school ={ schoolName:'中正國小'; dist:['大安里','幸福里','健康里','成功里'] ; 3Dnumber:[28,29,37,45]; } ``` 可以透過以下兩種方式存取 ``` school.schoolName; school.["schoolName"] ``` 後者[]方式好處是可以識別 JavaScript 不合法的字 `此物件object的[key]是 var school` #### 1-2 * 這個學校名字是中正國小,學生分別來至大安里,幸福里,健康里,成功里四個不同區的住戶小朋友 * 表示方法為 `var school ={ dist:['大安里','幸福里','健康里','成功里'] }` `此陣列的[key]是0,1,2,3` <p style="color:red"> 陣列可以計算數量 <kbd>length</kbd>,length可以被複寫,陣列的key可以做排序/反轉 </p> 兩種不同寫法 ``` var classNumber = 5; var classNumber = 8; var classNumber = 6; var classNumber = [5,8,6]; ``` ### 2.反轉資料 #### <span style="color:red">使用key來改變排序*只能用於陣列</span> ### 3.過濾資料方式 * 是在input type輸入名字,下方html 打印輸出該人年齡,input type綁定v-model="filterText" > * [v-model](https://cn.vuejs.org/v2/guide/components-custom-events.html#%E8%87%AA%E5%AE%9A%E4%B9%89%E7%BB%84%E4%BB%B6%E7%9A%84-v-model)使用於綁定物件 * scrpt data裡面新增 filterText: '' , 擷取文字 * 要在scrpt data裡面新增 filterArray: [ ]空陣列,作為後面methods 存取資料地方 * <p style="color:red">filter只用於array陣列</p> [filter參考資料](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Array/filter) * input type下方打印輸出篩選出來值表現方式 <kbd>:key="item.name"</kbd> ``` 本習題使用 存放人名,歲資料的arrayData裡面值有name & age兩種,所以用 {{ item.name }}置換{{ item.age }}也是可以的 <ul> <li v-for="(item, key) in filterArray" :key="item.age" > {{ key }} - {{ item.name }} {{ item.age }} 歲 </li> </ul> ``` > key 的特殊 attribute 主要用在 Vue 的虚拟 DOM 算法,在新旧 nodes 对比时辨识 VNodes。如果不使用 key,Vue 会使用一种最大限度减少动态元素并且尽可能的尝试就地修改/复用相同类型元素的算法。而使用 key 时,它会基于 key 的变化重新排列元素顺序,并且会移除 key 不存在的元素。 > > 有相同父元素的子元素必须有独特的 key。重复的 key 会造成渲染错误。 > > 最常见的用例是结合 v-for: ``` <ul> <li v-for="item in items" :key="item.id">...</li> </ul> ``` [引用vue官方資料來源](https://cn.vuejs.org/v2/api/#key) * 在input type 輸入文字篩選字串,需要一個function計算 ,寫在 var app methods: { }裡面 ,此function命名為 <b>filterData</b> * <span style="color:red">methods裡面this, 物件裡面函數裡的函數,直接指this可能會指定錯誤為最外層物件為this, 要給他一個代數來指稱 ex:<kbd>var vm = this </kbd> 在函數運算用<kbd>vm</kbd>替代this,方可重複使用 </span> > 參考本[章節,其他人文](https://blog.techbridge.cc/2019/02/23/javascript-this/),this只有在物件object裡面才有意義,嚴格定義下this是<kbd>undefined</kbd>,不嚴格定義瀏覽器底下是this可能是<kbd>window</kbd>或是node.js 底下是<kbd>global</kbd> > > 雖然this在不同使用情況下可能有不同預設值,但是可以透過其他方式改變預設值 * 1.filterArray(篩選function) = 在arrayData(存放人名歲數資料陣列)去篩選(filter) * 2.擷取item資料配對input type輸入文字 * 3.輸入item資料配對input type輸入文字 ``` filterData: function () { var vm = this ; vm.filterArray = vm.arrayData.filter(function (item) { console.log(item.name.match(vm.filterText)) return item.name.match(vm.filterText); }); }, ``` * 當在寫javascript效果時,為了除錯或是想知道,目前在這區間抓的值是否正確,將取到值直接秀在瀏覽器的開發者人員工具中. [參考console log資料](https://ithelp.ithome.com.tw/articles/10228902) ### 在javascript上能運作,但在vue無法直接運作(1)-click button啟動function修改array length 先在button上綁定 <kbd>@click="cantWork"</kbd>,並在methods裡面新增<kbd>cantWork:function</kbd>. 通常在javascript上直接修改length長度可以刪掉所有array代出來的資料,但是<span style="color:red"> vue無法直接透過刪除array length來刪除資料 </span> ``` cantWork:function(){ this.arrayData.length = 0; } ``` ### 在javascript上能運作,但在vue無法直接運作(2)-無法透過直接修改陣列索引來修改資料 舉例來說,如果要在第一筆資料[0]改成小強-99歲 * 0 - 小明 16 歲 * 1 - 漂亮阿姨 24 歲 * 2 - 杰倫 20 歲 在javscript通常會寫 ``` cantWork:function2(){ this.arrayData[0]={ name:'小強', age:99, } } ``` vue要修改陣列不能透過索引,需要透過[vue-set](https://cn.vuejs.org/v2/api/#Vue-set) <kbd>Vue.set( target, propertyName/index, value )</kbd> ``` cantWork2:function(){ Vue.set(this.arrayData,0,{ name:'小強', age:99, }) }, ``` ### 使用v-for在畫面產生純數字的迴圈 使用<kbd>v-for="item in number" </kbd>,如果要產生1-10,就是v-for="item in 10",如果是要產生1-15就是v-for="item in 15" ``` <ul> <li v-for="item in 15"> {{ item }} </li> </ul> ``` ### 搭配Template < tr>表格輸出 要在表格輸入array資料方法 在表格<kbd>tr</kbd>和<kbd>td</kbd>外面包一個<kbd><template v-for="item in array"> </template></kbd> ``` <table class="table table-bordered"> <template v-for="item in arrayData"> <tr> <td >{{item.name}}</td> <td>{{item.age}}</td> </tr> </template> </table> ``` ### v-for 與 v-if一起搭配使用 v-for 與 v-if一起搭配使用時,會先跑v-for再跑v-if. 例如:請輸入20歲以下的人 ``` <ul> <li v-for="(item, key) in arrayData" v-if="item.age <= 20"> {{ key }} - {{ item.name }} {{ item.age }} 歲 </li> </ul> ``` ### v-for 與 元件 ``` <ul> <list-item :item="item" v-for="(item, key) in arrayData" :key="item.name"></list- item> </ul> ``` ``` script var app = new Vue({}]外面新增 Vue.component('list-item', { template: ` <li> {{ item.name }} {{ item.age }} 歲 </li> `, props: ['item'] }); ``` 注意:現在建議元件使用 v-for 都加上 key。 [參考資料](https://cn.vuejs.org/v2/guide/list.html#%E5%9C%A8%E7%BB%84%E4%BB%B6%E4%B8%8A%E4%BD%BF%E7%94%A8-v-for) <iframe height="265" style="width: 100%;" scrolling="no" title="vue-v-for" src="https://codepen.io/corly74/embed/QWKzKyo?height=265&theme-id=dark&default-tab=html,result" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> See the Pen <a href='https://codepen.io/corly74/pen/QWKzKyo'>vue-v-for</a> by peiyun (<a href='https://codepen.io/corly74'>@corly74</a>) on <a href='https://codepen.io'>CodePen</a>. </iframe>