---
# System prepended metadata

title: '[Vue.js] 進階教學筆記'
tags: [Vue.js]

---

# [Vue.js] 進階教學筆記
###### tags: `Vue.js`


### 1.  關閉鈕aria-label：
一個 HTML attribute，用來告訴讀屏軟件某個元素是什麼。例如一個關閉按鈕「×」，視覺上看來都能理解，但是讀屏軟件並不能正確讀出，這時就可以用 aria-label 告訴它：
`<button aria-label="關閉">&times;</button>`

2. 關閉按鈕結合aria-hidden
```
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>

```
3. 刪除鍵的js語法
```
removeTodo: function(key){ 
      this.todos.splice(key , 1)}
      //串連html裡key的陣列值，再使用splice刪除陣列裡的幾筆資料
```    


### 4.  checkbox的連結語法：
下面有兩個元素，一個是checkbox，另一個是label，不管點哪一者都會得到一樣的結果，其原理是用 label for 對應checkbox的id，這樣兩者就會產生連動效果(html 的概念)；
input有個id，label有個for，兩者是透過id與for做連結
![](https://i.imgur.com/5hNMpzP.png)

```
//html code
<input type="checkbox" id="a1">
<label for="a1"></label>
```

### 5.  要綁定style的宣告，可使用class呼叫
:class="{'觸發completed': 條件item.completed}" 


```
  <li><a class="active" href="#">選項 1</a></li>
  
```
選項 1 不總是被選定的，而是依賴一個參數「isActive」決定－若 isActive 值為 true 才會被選定

```
<li><a :class="{ active: isActive }" href="#">顯示</a></li>
```
```
data: {isActive: true}
```

### 6. String.trim()  去除字串前後的空白
### 7. 利用時間製造獨一無二的亂數ID 
Math.floor(Date.now()) 取得現在時間
* Date.now() 可以取得現在 UTC timestamp 的 milliseconds (毫秒, 即千分之一秒)。只要將這個數值除 1000, 即可得到
* Math.floor() 函式會回傳無條件捨去後的最大整數

### 8. 迴圈forEach用法

forEach函式執行每個陣列內的物件或值
```
this.todos.forEach(function(item){ 
          if（item>2）{
          console.log(item)
          }}
//在this.todos陣列裡，使用item的資料做迴圈判斷    
          
```
### 9. 模板資料

Data使用<-span>型態
容易導致XSS攻擊，允許惡意程式將程式碼注入到網頁上





### 10. 動態切換className及style的方式

#### 一.基本用法
在style放入動態效果A跟B
在botton放上@click啟動，寫的方式是A=!A(點擊後會開啟)
在checkbox放上v-model啟動，寫入B的style名稱
在顯示位置上放入:class={'效果':條件}

#### 二.使用data統一管理
稱為：物件寫法
在data裡放上物件{A效果,B效果}
在顯示位置僅放入物件名稱就可以
在botton放上@click="物件名稱.A效果= !物件名稱.A效果"

#### 三.陣列方式
適用在不確定className長度，非用布林值，而是用陣列的方式加入，所有的效果都寫在html裡。

在data新增一個空陣列Classarry
在顯示位置放上陣列名稱Classarry
在checkbox1放上@click="陣列名稱" value="A效果"
在checkbox2放上@click="陣列名稱" value="A效果"


### 迴圈區別

[參考資料](https://www.ucamc.com/e-learning/javascript/261-javascript-reduce%E3%80%81foreach%E3%80%81filter%E3%80%81map)

* forEach：遍歷每個元素。
* map：遍歷每個元素，回傳的值會替代原本陣列內的值。
* filter：遍歷每個元素，回傳 true 時，目前的值會保留在陣列內，這會回傳一個新陣列，而不是修改原本的陣列。
* reduce：遍歷每個元素，依序組合、加總，然後丟給下個元素，最終會回傳一個結果。

### 11. 輸入的人名相同後便顯示相關資料，by迴圈filter

* Filter簡介
這個按照字面上的意思來說就是過濾器，filter 不會修改值，但他會幫你決定要不要將這個值留在陣列裡面，要注意的是 filter 會回傳一個新的陣列，而不是修改原本的陣列。


* 功用：當輸入的人名對應到陣列人名時，便可顯示此人的詳細資料
* 方式：將原陣列帶入filter迴圈裡，載入match公式，
為了將陣列做過濾，因而新增一個新陣列filterArray，將此陣列指到原陣列做迴圈(結論：陣列迴圈需要再創一個新陣列)。
使用filter公式做迴圈：this.arrayData.filter(function(item)){內容}
導入match公式 ： 陣列.match(輸入內容v-model串連的變數)
寫入的人名就對應match到陣列裡的人名就會顯示詳細資料



```
  <input type="text" class="form-control" v-model="filterText" @keyup.enter="filterData">
  <ul>
    <li v-for="(item, key) in filterArray" :key="item.age">
      {{ key }} - {{ item.name }} {{ item.age }} 歲 <input type="text" >
    </li>
  </ul>
```

![](https://i.imgur.com/J99Gt15.png)


```
 filterData: function () {
      var vm = this; //做for迴圈，this會被替換掉，此處宣告this就可以重新使用
      vm.filterArray = vm.arrayData.filter(function (item) { //將新增的filterArray陣列定義成==原本的陣列(arrayData)，套用filter迴圈公式代item值
        return item.name.match(vm.filterText); // 寫入的人名就對應match到陣列人名就顯示 //match公式 ： 陣列.match(輸入的內容)
      });
    },
```
> 在filter公式裡只要return是true狀態便會將item物件傳到vm.filterArray，直接顯示出來


### 12. Vue.set更改陣列內容

在vue要將新資料寫入陣列時，可使用 Vue.set(陣列array, 第幾筆index, value) 來達到修改資料目的

```
Vue.set(this.arrayData, 0, {
        name: '阿強',
        age: 99
      })
```
### 13. 迴圈使用template不輸出

```
<ul>
    <template v-for="(item,index) in foodsArray" :key="item.id">
      <li><span>{{item.name}}</span></li>
      <li><span>{{item.price}}</span></li>
    </template>
  </ul>
```

可將輸出群組化，且template不會被輸出
在html當作Dom元素，使用<template></template>載入v函式，並且不會出現在頁面中。

### 14. :key使用方式

v-for中的key
使用v-for更新已渲染的元素列表時,預設用就地複用策略;列表資料修改的時候,他會根據key值去判斷某個值是否修改,如果修改,則重新渲染這一項,否則複用之前的元素;注意上面key值不要用物件或是陣列作為key，用string或number作為key

```
 <ul>
    <li v-for="(item) in arrayData" :key="item.name"> 
     {{ item.name }} {{ item.age }} 歲 <input type="text">  
    </li>
  </ul>
```
:key
Vue 在更新 DOM 時是異步執行的，若不設定 key 值，不會重新渲染元素，只會部份更新。所以可給每個元素加上:key ，key值必須綁定一個唯一值，也就是確保每個元素的唯一性。

#### 說明 Vue 切換狀態可能遇到的問題
功能切換input項目內的狀態，先輸入username，後跳轉至email輸入，因兩者語法相似，需要個別增加不同key值程式(key="1"及"2")才能進行跳轉，否則程式會判定兩者語法一樣而僅做工一則

```
  <template v-if="loginType === 'username'">
    <label>Username</label>
    <input class="form-control" placeholder="Enter your username" :key="1">
  </template>
  <template v-else>
    <label>Email</label>
    <input class="form-control" placeholder="Enter your email address" :key="2">
  </template>
  <button class="btn btn-outline-primary mt-3" @click="toggleLoginType">切換狀態</button>
  <hr>
```

### 15. v-if及v-show的差異

[參考資料](https://cythilya.github.io/2017/04/22/vue-conditional-rendering/)

![](https://i.imgur.com/FQ48XU7.png)


v-if只會渲染滿足條件的而隱藏另一條件，
![](https://i.imgur.com/eCZTLqh.png)

v-show會渲染滿足條件的，然後顯示關閉另一條件。
![](https://i.imgur.com/6gZFdgM.png)


### 16.v-for與v-if 優先權的比較
v-for的優先權高於v-if，因此當兩者皆出現在同一個元素上時，v-if會隨著v-for重覆執行數次。


### 17. watch當變數產生變化，便會執行特定function

當特定的變數產生變化，會執行特定的function。
範例，當trigger點擊後三秒將trigger布林值修改成false
```
<p>使用 trigger 來觸發旋轉 box、並在三秒後改變回來</p>
  <div class="box" :class="{'rotate': trigger }"></div>
  <hr>
  <button class="btn btn-outline-primary" @click="trigger = true">Counter</button>
```

```
    watch:{
      trigger:function(){
        var vm = this;
        setTimeout(() => {
          vm.trigger = false
        }, 3000);
      }
    },
```
＊補充：watch非放置在computed內，而是平行階層


### 18. mounted時間格式

Computed 來呈現時間格式：
這邊我們會用到 mounted，它同樣是 vue 提供的 api，意義是當我們畫面運行完畢之後執行某段程式碼。

＊ 補充：mounted，而是平行階層

```
// 1. mounted 等待運算結束後在掛載上後續要做的事情
// 2. 先把 newDate 放到第二個 p 標籤裡面看看會是呈現什麼

<p>使用 Computed 來呈現時間格式。</p>
<p>{{ newDate }}</p>

mounted: function() {
    this.newDate = Math.floor(Date.now() / 1000);
},

```

畫面會出現一串數字是 timeStamp 可以透過 JS 來轉換成我們人所看得懂的日期格式，這裏我們用 computed 來改成我們日常看得懂的格式。

```
computed: {
    formatTime: function() {
        console.log(this.newDate
        
        // 用 new Date 把值轉回原本的時間格式，newDate 時間長度可能不足所以 * 1000補回原本長度
        let dates = new Date(this.newDate * 1000);
        
        // 以下都是取出時間格式的方法
        let year = dates.getFullYear();
        let month = dates.getMonth() + 1;
        let date = dates.getDate();
        let hours = dates.getHours();
        let minutes = dates.getMinutes();
        let seconds = dates.getSeconds();
        
        // 最後將我們時間的格式拼成我們所要的
        return `${year}/${month}/${date} ${hours}:${minutes}:${seconds}`
    }
}
```
![](https://i.imgur.com/X9dGUuh.png)

### 19. forEach迴圈

目的：在原陣列裡做if判斷式，並顯示不同的結果

```
const items = ['item1', 'item2', 'item3'];
const copy = [];

items.forEach(function(item){
  copy.push(item)
});
```


搭配computed函數宣告使用，先宣告一組空陣列copy，此時套用forEach公式並把篩選後的結果push至新陣列copy裡，顯示在畫面上。

> function裡的item是變數，可任意更改，但盡量還是統一使用

```
if(this.visibility == 'active'){ //重點部分，剩兩個部分用判斷式(completed的布林值)來區分
        var newTodos=[]; //新陣列
        this.todos.forEach(function(item){ //forEach函式執行每個陣列內的物件或值，取用原先todos
          if(!item.completed){
            newTodos.push(item); //符合條件的輸入至新的陣列newTodos裡
          }

        })
        return newTodos;
      }
```



