###### 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>