0%

試想今天有一個網頁,上方的導覽列有不同的分類,帶領你到該項目的分頁中
那我們該如何實現,將各個項目的內容一一呈現

簡單分別製作 component

首先:component的命名要用大寫

  • 在 component 中
  • 在 App.vue
    讓vue知道有個component可以被使用,透過ES6的解構放入

    將引入的component放到template

將其他組件引入

補充說明:

修改路徑:
用~@來指定圖片路徑:@在vuecli是代表特殊意義,就會直接從src這個資料夾底下開始查找;而波浪符號,代表現在在css之中使用這個功能

  • 也就是在專案中,即便路徑複雜,只要在路徑最前面加上@就會直接進去src

之所以會撰寫這篇文,是因為面試過程被考倒的觀念,才發現自己過去從沒注意到這部分啊,那就來寫篇文章來認識它們之中的傳遞方式。

首先,先從型別的認識開始

在Javascript分兩大類,一種是基本型別(primitive type),另一種是物件(Object)。

  • Primitive type (以純值的形式存在)
    Boolean
    Null
    Undefined
    Number
    BigInt
    String
    Symbol(於 ECMAScript 6 新定義)
  • Object
    物件型別指的是可能由零或多種不同型別 (包括純值與物件) 所組合成,例如object,array, function, map

知道型別後,可以簡易的分類:

  • primitive type會是 pass by value,
  • object 是 pass by reference。

接下來來觀察,它們之間不同

pass by value

範例1:

1
2
3
4
5
6
7
let x=10;
let y=x;

x=20;
console.log(x); //20
console.log(y); //10

  • 注意:x和y是兩個獨立變數 (先記著這點)
    • 值會存入該變數
      var y = x; 看起來會像是y的內容要複製x,但可以的話要理解為,變數 y 是去建立了一個新的值,然後將變數 x 的內容複製了一份過來。
  • 因為兩的變數,各自獨立,所以當變數 x 的內容後來經過更新變成 20 之後,變數 y 的內容依舊保持原來的 10 而不受影響。

範例2

1
2
3
4
5
6
7
8
9
10
11
var num=3;
console.log("num start:",num);

function passByValue(func_num){
func_num=5;
}

passByValue(num);

console.log("num end:", num);

結果:

1
2
3
num start:3
num end: 3

  • 先是宣告新變數
  • 隨後建立passByValue() 函式
  • 呼叫passByValue(num) 複製變數num的值,3傳入passByValue(func_num)
    • 一開始 值會是3
    • 遇到func_num=5; => 將值改為 5
  • 但因為出去了函式範圍(scope),最終的值 num end:3

pass by refrence

範例

1
2
3
4
5
6
7
8
let x={value:10};
let y=x;

x.value=20;
console.log(x); //{value:20}
console.log(y); //{value:20}
console.log( x === y ); //true

拆解說明一下

  • 當宣告一個物件
  • JavaScript 會在記憶體的某處建立起一個物件 (圖右側),然後再將這個 x變數指向新生成的物件

  • 接著,當我們宣告了第二個變數 y ,並且透過 = 將y 指向 x 的位置。
  • 接著當我們更新了 x.value 的內容後, y.value 的內容也被更新了。

範例2

1
2
3
4
5
6
7
8
9
10
11
12
var obj1={item:"unchanged"};

console.log("obj1 start:",obj1);

function passByReference(ref){
ref.item= "changed";
}

passByReference(obj1);

console.log("obj end", obj1);

結果

1
2
3
obj1 start:{item: "unchanged"}
obj1 end:{item:"changed"}

  • 當執行passByReference(obj1) 。想像他是個地址(0x0016),進入函式中將地址複製,傳入。
    • 此時他的value 是個地址(0x0016)
  • 進入函式,遇到ref.item
    • de-reference ,進入原本的記憶體位置,找到item,並改變他的值

在不一般情況下,基本型別是 pass by value,而物件型別是 pass by reference的方式,但總有例外的時候。

pass by sharing

1
2
3
4
5
6
7
8
9
10
11
12
var obj1={item:"unchanged"};

console.log("obj1 start:",obj1);

function passBySharing(ref){
ref={ item: "changed"};
}

passBySharing(obj1);

console.log("obj end", obj1);

1
2
3
obj1 start:{item: "unchanged"}
obj1 end:{item:"unchanged"}

  • 傳入之前start 沒有改變
  • 呼叫函式,並進入passBySharing(),還是複製地址,傳入
  • 遇到ref={ item: "changed"};,會直接覆蓋地址(有點類似pass by value)
    • 這並不是直接更改物件特性

最後,來說說 JavaScript 屬於?

看了多篇文章,實在也是有點混亂,該認為三種形式都有呢?還是就是Pass by sharing、Pass by reference呢? 那例外情形又該如何解釋?

所以這邊的結尾,直接引用Kuro、Huli老師文章的資訊,供給大家參考。

從Kuro Hsu 的文章
提及認為 JavaScript 應該更屬於 Pass by sharing 的形式。

  • JavaScript 不屬於單純的傳值或傳址。

參考 ECMA-262-3 in detail. Chapter 8. Evaluation strategy

Regardless of usage concept of reference in this case, this strategy should not be confused with the “call by reference” discussed above. The value of the argument is not a direct alias, but the copy of the address.
由於在 JavaScript 的物件類型是可變的 (mutable),當物件更新時,會影響到所有引用這個物件的變數與其副本,修改時會變動到原本的參考,但當賦與新值時,會產生新的實體參考。

另外在 Huli 的文章中:

依據細分程度的不同,下面幾句話都是正確的:
JavaScript 裡面只有 pass by value
JavaScript 的 primitive type 是 pass by value,object 是 pass by sharing


最終來個綜合練習:

相信在最後的這個練習,可以更清楚,pass by value,pass by reference,pass by sharing

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function changeStuff(num,obj,obj2){
num=num*10;
obj.item="changed";
obj={item:"changed"};
}

var num=10;
var obj={item: "unchanged"};
var obj2= {item: "unchanged"};

changeStuff(num, obj, obj2);
console.log(num);
console.log(obj.item);
console.log(obj.item);
1
console=> 10 "changed" "unchanged"

參考資料:
JS基本觀念:call by value 還是reference 又或是 sharing?
重新認識 JavaScript: Day 05 JavaScript 是「傳值」或「傳址」?
Tech Talk: Pass By Sharing with Javascript
深入探討 JavaScript 中的參數傳遞:call by value 還是 reference?

延續 Wilson Ren課程來認識常見的排列方法!

排列的演算法介紹

  • 在JS中,就有內建 array.sort()
    • 同樣在其他程式語言,都會有內建的 sorting function
    • 但還是需要知道他們是如何運作
  • 總共有 6 種 sorting
  • 此篇文章會以前面兩種為主

Bubble Sort

  • 冒泡排序
  • 會比較相鄰的元素,如果順序不對會互換element
  • 是相當簡單的演算法,在現實世界很少拿來使用,最常用在教學
  • 而像在python、java 他們內建的排序演算法,都不是用冒泡排序,多是用 quicksort,merge sort(比較複雜、但有效率)

    範例說明

  • 比較array的最後兩個數字 => 發現順序不對就對調
  • 對調之後,再往下兩個元素
    • 發現順序正確,不需更動
  • 不更動之後,再往下兩個

    以此類推…
  • 小結:將找到的最小值,推到最左邊

要如何做 Bubble Sort

  • 先從一個陣列中2個數值比較開始思考

    1
    2
    3
    for j from A.length-1 to 1;
    if A[j] < A[j-i] ;
    swap A[j] and A[j-i]
  • 虛擬碼

  • i => sorted elements

  • j => adjacent elements(j是相對i而來)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    function bubbleSort(arr){
    for(let i=0;i<arr.length-2;i++){
    for(let j=arr.length-1;j>=i+1;j--){
    if (arr[j]<arr[j-1]){
    //swap arr[j] and arr[j-1]
    let temp=arr[j];
    arr[j] = arr[j-1];
    arr[j-1] = temp;
    }
    }
    }
    console.log(arr);
    }

    bubbleSort([4,1,5,2,7]);
  • 加入隨機的數字,組成新的陣列

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    function bubbleSort(arr) {
    let step = 0;
    for (let i = 0; i <= arr.length - 2; i++) {
    for (let j = arr.length - 1; j >= i + 1; j--) {
    if (arr[j] < arr[j - 1]) {
    // swap arr[j] and arr[j - 1]
    let temp = arr[j];
    arr[j] = arr[j - 1];
    arr[j - 1] = temp;
    step++;
    }
    }
    }
    console.log("It takes " + step + " steps to complete.");
    console.log(arr);
    }

    let test = [];

    for (let i = 0; i < 100; i++) {
    test.push(Math.floor(Math.random() * 100));
    }

    bubbleSort(test);

    Big O of Bubble Sort

  • 最糟情況下: 由大到小,要排成 由小到大 => 他交換的次數會是 (n-1)+(n-2)+(n-3)+…+(n-n)次

  • 最好的情況: 本身的arr就接近 小到大

    • 優化語法
    • 發現沒有任何elements被交換,就可以停止迴圈
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      function bubbleSort(arr){
      for(let i=0;i<arr.length-2;i++){
      let swapping=false;
      for(let j=arr.length-1;j>=i+1;j--){
      if (arr[j]<arr[j-1]){
      //swap arr[j] and arr[j-1]
      let temp=arr[j];
      arr[j] = arr[j-1];
      arr[j-1] = temp;
      swapping=true;
      }
      }
      }
      if (swapping==false){
      break;
      }
      }
  • 平均情況還是用到 nested for loop

    • O(n^2)

Insertion Sort

  • 效率比 bubble sort 好一些
  • 理論上, 都是 O(n^2)
  • 不斷做插入的動作

    範例說明

  • 先認為這條arr長度是1
  • 從陣列最前面開始,要將1插入4這個arr上

  • 數字2,要和左邊的數字作比較

  • 數字3去比較

虛擬碼

1
2
3
index 0,1,2,3,4
value 1,2,3,4,0

  • 檢查這條arr的 index=1
  • 設定key=A[j],並將key插入 sorted sequence
    • j 的前一格為 i
  • 確認 i 有沒有大於key => 也就是對於key而言,要不斷地和它左邊的值比較
    • 如果左邊的值比key大,就要讓他們互換
1
2
3
4
5
6
7
index 0,1,2,3,4
value 1,2,3,4 (i),0 (j key)

while i>0 && A[i] > key
A[i+1] = A[i]
i -= 1

  • 語法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
let unsorted = [14, -4, 17, 6, 22, 1, -5];

insertionSort(unsorted);

function insertionSort(arr) {
for (let j = 1; j <= arr.length - 1; j++) {
let key = arr[j];
i = j - 1;
while (i >= 0 && arr[i] > key) {
arr[i + 1] = arr[i];
i -= 1;
}
arr[i + 1] = key;
}

console.log(arr);
return arr;
}

Big O

常常看到 YouTube 演算法造成頻道經營的難度、或是facebook演算法而使得行銷曝光度的改變,但始終對演算法這個名詞沒有認識。
藉由 Wilson Ren課程

什麼是演算法?

用以解決問題而可以逐步執行的步驟或程序。

來看看現實生活中的演算法

  • Google Map 如何找到最短路徑
  • YouTube 推薦給你,認為你有興趣的影片
  • FB\IG 的加好友、追蹤推薦

演算法比較

有兩個演算法都可以完成目標任務,那我們會如何取決誰比較好?

  • 哪個演算法執行速度快?
  • 所佔用電腦的記憶體資源少?

    時間?

    首先,在計時演算法所耗時的部分:
  • 幫演算法做計時,是不實際的事情
    • 同一台電腦在執行同一任務,所執行的時間會不同
    • 不同電腦、CPU處理速度不一樣

      應該考慮,複雜度 Complexity

  • 複雜度分為兩種:時間複雜度、空間複雜度 (在本文多是討論時間複雜度)
  • 要如何計算時間複雜度?
    • 加、減、乘、除、comparison ,這些每一個都可以被算作一個 operation
    • Complexity: 在所寫的演算法中,總共用到多少 operations(運算子)
    • 使用 function 來顯示 Complexity 和 input size 的關係。

Big O Notation

  1. 是一個工具,用來描述當你的值不斷擴大時,f(n)值會去哪裡
  2. 為最壞情況的打算。他會展示一個演算法複雜度的趨勢

計算 Big O 的值

  1. Constant doesn’t matter : 常數它並不重要
    • f(n)=3n :3為常數、n為變數
  2. Small Terms don’t matter
    • fn= 3n^2 + 6n + 4 => 只需保留到fn= 3n^2
  3. Logarithm Base doesn’t matter

    範例:

  4. f(n)=3n
    答案:O(n)
  5. f(n)=13n^3 + 6n +7
    答案:O(n^3)
  6. f(n)=4log₂n
    答案:O(logn)
  7. f(n)=5
    答案:O(1)

演算法常見 Big O 的值

由好至差

  1. O(1)
  2. O(logn)
  3. O(n)
  4. O(nlogn)
  5. O(n^2)
  6. O(n^3)
  • 很多sorting值會是 O(nlogn)
  • 盡量讓演算法可以達到3、4的值

圖示:

emit 實作練習

  • 透過點擊add按鈕,觸發外層元件數值的改變
    • 先定義外層接收資料方式
    • 定義內層的 $emit 觸發方法
    • 使用 v-on 的方式觸發外層方法(口訣:前內、後外)

外層元件

  • 定義接收方法:當內層傳給你的時候,要做什麼事
    • addNumber()使num 增加1
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      const app = Vue.createApp({
      data() {
      return {
      num: 0,
      text: ''
      };
      },
      methods: {
      addNumber() {
      console.log('addnumber');
      this.num++;
      },

      }
      });

內層元件

  • 在方法內建立函式,來觸發資料傳遞
  • 並將click綁到內部元件的按鈕上。使點擊時候,會觸發$emit
    • emit 名稱emit-num
      1
      2
      3
      4
      5
      6
      7
      8
      9
      app.component('button-counter', {
      methods: {
      click() {
      console.log('inner,click');
      this.$emit('emit-num');
      }
      },
      template: `<button type="button" @click="click">add</button>`
      });

建立內外層元件的溝通橋樑

  • 使用 v-on 的方式觸發外層方法(口訣:前內、後外)
    • 在 div內放入子元件button-counter
    • :emit-num="addNumber"
1
2
3
4
<div id="app">
{{ num }}
<button-counter v-on:emit-num="addNumber"></button-counter>
</div>

練習二,資料接收

外層元件

  • 接收方法為 getData 接收 text
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    const app = Vue.createApp({
    data() {
    return {
    text: ''
    };
    },
    methods: {

    getData(value) {
    console.log('getData', text);
    this.text = value;
    }
    }
    });

內層元件

  • 建立觸發傳遞的方式
    • 將內層元件text: '內部資料' 傳遞到外層
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      app.component('button-text', {
      data() {
      return {
      text: '內部資料',
      }
      },
      methods: {
      emitText() {
      this.emit('emit-text', this.text)
      }
      },
      template: `<button type="button" @click="emitText">emit data</button>`
      });

      建立內外橋樑

      1
      2
      3
      <h3>傳遞資料狀態</h3>
      內部傳來的文字:{{ text }}<br>
      <button-text @emit-text="getData"></button-text>

emit 命名

與 props 命名一樣需要注意:

  • 在內層若以駝峰命名 emitText
    • 也可以一開始內層就是用- 來命名即可,如emit-text
      1
      2
      3
      emitText() {
      this.emit('emitText', this.text)
      }
  • 到了要綁定的 template 上,emit-text
    1
    <button-text @emit-text="getData"></button-text>

因為Vue每個元件都是各自獨立,所以我們無法在各自元件去調整資料,而直接修改另一個元件的資料。
所以,要使元件之間可以相互溝通,就需要使用資料傳遞方式。
在傳遞方式:

  • 外層傳遞內層 : props
  • 內層向外傳遞 : emit
    當外層元件,要將資料往內層元件丟時,此過程就是使用props。

傳遞資料的方式:

靜態資料傳入

  • 預期將外層傳入一個url的變數,傳進給內層使用
    • photo為內部元件,在template 我希望能夠取得外層傳入的圖片(urlimg)
    • 故在 props 以此命名,並將它綁到 template
      1
      2
      3
      4
      app.component('photo', {
      props: ['url'],
      template: `<img :src="url" class="img-thumbnail" alt>`
      });
  • 將上方的元件資料,加到外層元件:像是加入html屬性一樣
    1
    2
    3
    <photo
    url="https://images.unsplash.com/photo-1605784401368-5af1d9d6c4dc?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=600&q=80">
    </photo>

動態資源

  • 使用 v-bind,綁定內部元件的props ,使資料可以跟外層元件連動
  • 記得使用口訣: 前內、後外 =>前面就是props內的名稱,後面就是外層元件的名稱
    1
    2
    3
    <h3>動態資源</h3>
    <p>技巧:前內、後外</p>
    <photo v-bind:urlimg="imgUrl"></photo>

資料傳遞為 單向數據流

  • 外部所定義的資料,當往內層傳遞,是單向性
  • 不能試圖使用v-model或各種方式,來改變props傳入的內容
    • 以下範例:在子元件 photo2 放入 input綁定 v-model
    • 當嘗試在輸入框修改網址,會出現錯誤
1
2
//外層元件綁定 url
<photo2 :url="imgUrl"></photo2>
1
2
3
4
5
6
7
8
9
10
11
12
13
const app = Vue.createApp({
data() {
return {
imgUrl: 'https://images.unsplash.com/photo-1605784401368-5af1d9d6c4dc?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=600&q=80',
};
},
});

app.component('photo2', {
props: ['url'],
template: `<img :src="url" class="img-thumbnail" alt><br>
<input type="text" v-model="url"> {{ url }}`
})

在內部元件,要為props來命名

在命名上有些要注意的地方

  • 首字母大寫: PostData、SetItems
  • 駝峰命名法: postData、setItems
    要注意:在 HTML 中使用時必須使用 kebab-case (短橫線分隔)且應該為小寫。
1
2
3
4
5
6
7
8
9
10
11
<div id="app">

<photo3 :super-url="imgUrl" ></photo3>
</div>

<script>
Vue.component("photo3", {
props: ["superUrl"],
template: `<img :src="superUrl" class="img-thumbnail alt >"`
});
</script>

定義 Props 型別驗證

  • 使用型別驗證,會改用大括號,裡面放入props名稱,並用物件形式加入設定的內容
    • props:{ propC: { type: String, required: true, } }
  • 其中,可以針對該props 來設定:
    • type型別 : 可以是 String、Number、Boolean、Array、Object、Date、Function、Symbol
    • default :如果該 prop 沒有接收到傳入的值,就會使用 default 的值作為預設值。
    • required : 是否為必填項,如果設為 true 則表示必須要有值傳入,若沒有,就會出現錯誤提示。
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      app.component('props-validation', {
      props: {
      // 單一型別檢查,可接受的型別 String, Number, Object, Boolean, Function(在 Vue 中可使用 Function 驗證型別)
      // null, undefined 會直接通過驗證
      propA: Function,

      // 多個型別檢查
      propB: [String, Number],

      // 必要值
      propC: {
      type: String,
      required: true,
      },

      // 預設值
      propD: {
      type: Number,
      default: 300
      },

      // 自訂函式
      propE: {
      type: Object,
      default() {
      return {
      money: 300
      }
      }
      },

      // 自訂驗證
      propF: {
      validator(value) {
      return value > 1000
      }
      },
      },
      六角學院
      [DAY12]跟 Vue.js 認識的30天 - Vue 模組資料傳遞(props)

修飾符有分為:
1.按件修飾符
2.滑鼠修飾符
3.事件修飾符

codepen

按鍵修飾符

1-1. 別名修飾

  • 在特定按鍵,按下去的時候觸發
    • .enter, .tab, .delete, .esc, .space, .up, .down, .left, .righ
  • 使用.enter只有再按下 enter 鍵才會觸發
1
2
3
4
5
<div id="app">
<h6 class="mt-3">別名修飾</h6>
<input type="text" class="form-control" v-model="text" @keyup.enter="trigger('enter')">

</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
Vue.createApp({

data(){
return {

}
},
methods: {
trigger: function(name) {
console.log(name, '此事件被觸發了')
},
}
}).mount('#app')

1-2. 相應按鍵時才觸發的監聽器

  • 僅在按下相應按鍵時才觸發鼠標或鍵盤事件的監聽器
  • .ctrl, .alt, .shift, .meta
  • 此範例為 @keyup.shift.enter
    1
    2
    <h6 class="mt-3">相應按鍵時才觸發的監聽器</h6>
    <input type="text" class="form-control" v-model="text" @keyup.shift.enter="trigger('shift + Enter')">
  1. 滑鼠修飾符
    .left 只當點擊鼠標左鍵時觸發。
    .right 只當點擊鼠標右鍵時觸發。
    .middle 只當點擊鼠標中鍵時觸發。
  • 按下滑鼠右鍵
    <span class="box" @click.right="trigger('right button')">
1
2
3
4
5
6
<h4>滑鼠修飾符</h4>
<h6 class="mt-3">滑鼠修飾符</h6>
<div class="p-3 bg-primary">
<span class="box" @click.right="trigger('right button')">
</span>
</div>

  1. 事件修飾符
  • 不會限定,是使用滑鼠還是鍵盤,是針對事件本身來進行修飾
    .stop - 調用 event.stopPropagation()
    .prevent - 調用 event.preventDefault()
    .capture - 添加事件偵聽器時使用 capture 模式。
    .self - 只當事件是從偵聽器綁定的元素本身觸發時才觸發回調。
    .once - 只觸發一次回調。
  • 常用的是 <a>外部連結:移除預設事件
    1
    2
    3
    4
    5
    6
    7
    8
    9
    <h4>事件修飾符</h4>
    <ul>
    <li>.stop - 調用 event.stopPropagation()。</li>
    <li><strong>.prevent - 調用 event.preventDefault()。</strong></li>
    <li>.capture - 添加事件偵聽器時使用 capture 模式。</li>
    <li>.self - 只當事件是從偵聽器綁定的元素本身觸發時才觸發回調。</li>
    <li>.once - 只觸發一次回調。</li>
    </ul>
    <a href="https://www.google.com/" @click.prevent="trigger('prevent')">加入 Prevent</a>

資料來源:
六角學院 - Vue 3.js

前言

之前在安裝套件時,就有先安裝過 Node.js 但從沒有特別去注意,它是應用在哪一塊、可以做什麼?就找了之前 udemy 全端課程,特意拉此部分來認識一下。

Node.js,讓我們可以將js檔案拿出瀏覽器,並直接和電腦硬件互動

  • js: 進行網頁中的實作、函式、行為的建立。動畫的執行、下拉選單
  • Node.js: 允許我們用JS 直接與電腦的硬體互動。例如建立桌面應用程式
  • 此外,還能在別人的電腦或server用Node.js來用行JS。例如:使用者登入 google 並輸入詢問,而你的瀏覽器會發出請求給google servers,而在這些servers 可以真的執行JS程式碼來執行發出的請求

如何使用Node

  1. 首先,建立一個資料夾 intro-to-node,在資料夾內建立檔案index.js
  2. 在該資料夾位置,運行node index.js

  • 印出檔案內的console

node REPL

  • Read Evaluation Print Loop
  • 要進入:就是在終端機下node
  • 和google 的console有點類似
  • 取得些提示 con+ tab 會列出相關的可能性

    離開

  • .exit
  • control+c 兩次
  • clear 可以清除終端機的資料

    native node module

  • 當安裝node,他就會包含許多建立好的模組

    使用node.js 進入電腦本地端的資料

  • nodejs.org/api 可以查到所有native node module,以及使用方式說明的文件
  • 當要使用 modual

  • 警告 jshint esversion:6

實際應用練習:複製檔案

  • 在原本的資料夾內建立新的檔案

  • 在index.jd 輸入該語法
  • 輸入後要運行 node index.js
    • 運行之後會看到 file2 建立完成
  • 若是已經建立好的檔案
  • 在檔案內輸入資訊I am file2
  • 執行 copyFileSync

NPM package manager

如何使用真實npm

  • 在要進行安裝的資料夾內,npm install superheroes

  • 參考文件的說明
    • 在js檔案中輸入
    • 運行 node index.js

什麼是 Node.js?Node.js 完整介紹懶人包!

v-for 呈現多筆陣列

  • v-for= item in peopleArr , item 為 自定義名稱,後面(peopleArr)填入要迴圈的資料
    • item是表示 peopleArr 陣列中每個單一物件
  • key :為帶入陣列的 key 值
1
2
3
4
5
6
7
8
9
10
11
<div id="app">
<h3>v-for 與 key</h3>
<p> 人員介紹</p>
<ul>
<li v-for="(item, key) in peopleArr">
{{ key }} - {{ item.name}} / {{ item.age }} 歲
</li>
</ul>

</div>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
Vue.createApp({

data(){
return {
peopleArr: [
{
name: 'Ken',
age: 30,
vegan: false
},
{
name: 'Wong',
page: 35,
vegan: false
},
{
name: 'Merry',
age: 60,
vegan: false
},
{
name: 'Tom',
age: 30,
vegan: true
},
],
}
},

}).mount('#app')

codepen

物件迴圈

  • 每個item 就是每個物件的資料
  • key值為物件的屬性名稱
1
2
3
4
5
6
7
8
9
10
11
12
<div id="app">
<h3>v-for 與 key</h3>
<p> 人員介紹</p>
<ul>
<li v-for="(item, key) in peopleObj">
{{ key }} - {{ item.name}} / {{ item.age }} 歲

</li>
</ul>

</div>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
Vue.createApp({

data(){
return {
peopleObj:{
Salse: {
name: 'Ken',
age: 30,
vegan: false
},
Manager: {
name: 'Wong',
page: 35,
vegan: false
},
HumanResource: {
name: 'Merry',
age: 60,
vegan: false
},
Crew: {
name: 'Tom',
age: 30,
vegan: true
}
},
}
},

}).mount('#app')

v-for 與 key

v-for 可以使用 index 當作 key 嗎?

以六角課程為範例說明

1
2
3
4
5
6
7
8
<h3>v-for 與 key </h3>
<p>菜單</p>
<ul>
<li v-for="(item, key) in products">
{{ key }} - {{ item.name}} / {{ item.price }} 元
<input type="text">
</li>
</ul>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
Vue.createApp({

data(){
return {
products: [
{
name: '蛋餅',
price: 30,
vegan: false
},
{
name: '飯糰',
price: 35,
vegan: false
},
{
name: '小籠包',
price: 60,
vegan: false
},
{
name: '蘿蔔糕',
price: 30,
vegan: true
},
],
},
method:{
reverseArray: function () {
this.products.reverse();
},
}
}
}).mount('#app')

  • 反轉之後,並沒有跟著

  • 綁定key之後

    1
    <li v-for="(item, key) in products" v-bind:key='item.name'>

v-for 可以使用 index 當作 key 嗎?

索引是依照位置來判定,所以當資料的位置修改,索引值也會跟著變動,導致後續的渲染錯誤。
如果key是會變動的話,可能會導致資料的渲染錯誤

如果後端提供的資料,沒有唯一索引要如何處理?

1.與後端溝通,為何前端要用到key的值
2.拿到資料後,自己產生key,並放入該物件資料中

1
2
3
使用v-for時,一定要用key 
使用v-for時,不要拿索引當作key
請使用唯一的值當作key的值

使用v-model來進行資料的「雙向」綁定, v-model 會根據不同的表單類別來更新元素的內容。
主要應用在表單類型進行綁定,常見的表單元素像是 <input><textarea> 以及 <select> 等。

v-model 可以與 input 、textarea 綁定

1
2
3
4
<h3>input</h3>
<input type="text" class="form-control" v-model="name">
{{ name }}

1
2
3
4
5
6
7
8
9
Vue.createApp({

data(){
return {
name: "小明"
}
},

}).mount('#app')

1
2
3
<h3>textarea</h3>
<textarea cols="30" rows="3" class="form-control" v-model="text"></textarea>
{{ text }}
1
2
3
4
5
6
7
8
9
Vue.createApp({

data(){
return {
text: "一段文字敘述"
}
},

}).mount('#app')

checkbox 單選框

  1. checkbox與p段落連動
  • 在input加入v-model="checkAnswer"
  • P段洛,放入三元運算:用來判斷當checkAnswer為true,顯示’吃飽了’;反之,’還沒’
    • 透過選單的勾選,來顯示 checkAnswer 是 true \ false
1
2
3
4
5
6
7
 <h3>checkbox 單選框</h3>
<p>小明,你是吃飽沒?</p>
<p>{{ checkAnswer ? '吃飽了' : '還沒'}}</p>
<div class="form-check">
<input type="checkbox" class="form-check-input" id="check1" v-model="checkAnswer">
<label class="form-check-label" for="check1">小明回覆</label>
</div>
1
2
3
4
5
6
7
8
9
Vue.createApp({

data(){
return {
checkAnswer: false,
}
},

}).mount('#app')

  1. checkbox 單選延伸
  • 回傳單一的值,相對使用三元運算比較直觀
  • checkAnswer2 是空字串,在 input 綁定後,設定false-value、true-value
  • 將文字綁入:true-value="吃飽了" false-value="還沒",就可以放入資料欄位上
1
2
3
4
5
6
7
8
<h3>checkbox 單選延伸</h3>
<p>小明,你是吃飽沒?</p>
<p>{{ checkAnswer2 }}</p>
<div class="form-check">
<input type="checkbox" v-model="checkAnswer2" true-value="吃飽了" false-value="還沒" class="form-check-input"
id="check2">
<label class="form-check-label" for="check2">小明回覆</label>
</div>
1
2
3
4
5
6
7
8
9
Vue.createApp({

data(){
return {
checkAnswer2: '',
}
},

}).mount('#app')

checkbox 複選框

  • 資料格式為陣列
  • 覆選框的input裡面要有value
  • 當綁定v-model,於畫面點選該項目時,會將 input 中的 value,放入的陣列中
    • 最後將資料渲染於畫面
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      <h3>checkbox 複選框</h3>
      <p>你還要吃什麼?</p>
      <p>{{ checkAnswer3.join('') }}</p>
      <div class="form-check">
      <input type="checkbox" class="form-check-input" id="check3" value="蛋餅" v-model="checkAnswer3">
      <label class="form-check-label" for="check3">蛋餅</label> </div>
      <div class="form-check">
      <input type="checkbox" class="form-check-input" id="check4" value="蘿蔔糕" v-model="checkAnswer3">
      <label class="form-check-label" for="check4">蘿蔔糕</label>
      </div>
      <div class="form-check">
      <input type="checkbox" class="form-check-input" id="check5" value="豆漿" v-model="checkAnswer3">
      <label class="form-check-label" for="check5">豆漿</label>
      </div>
      1
      2
      3
      4
      5
      6
      7
      8
      9
      Vue.createApp({

      data(){
      return {
      checkAnswer3: [],
      }
      },

      }).mount('#app')

v-model 修飾符

修飾符為畫面上,v-model的資料和實際data中的資料在綁定之間,額外處理的小方法。

  1. 延遲 Lazy
  • 輸入文字後,要點擊外面或是按下enter,才會出現
  • 綁定到html的change事件:當完成輸入框的事件之後,才會綁定到資料集
    1
    2
    3
    4
    <h3>修飾符</h3>
    <h4 class="mt-3">延遲 Lazy</h4>
    {{ lazyMsg }}
    <input type="text" class="form-control" v-model.lazy="lazyMsg">

純數值 Number

需要用戶輸入數值,可先將type改為number,並加入修飾符

  • <input type="number">:輸入框無法輸入文字,只能輸入數字,但型別依然是string
1
2
3
<h4 class="mt-3">純數值 Number</h4>
{{ numberMsg }}{{ typeof numberMsg }}
<input type="number" class="form-control" v-model="numberMsg">

  • 要確保輸入的內容為純數字型別:要加修飾符
1
2
3
<h4 class="mt-3">純數值 Number</h4> 
{{ numberMsg }}{{ typeof numberMsg }}
<input type="number" class="form-control" v-model.number="numberMsg">

trim

將資料內容的前後空白鍵,刪除

  • 應用於要輸入e-mail帳號,避免用戶不小心在前後加入空白,而造成資料錯誤
    1
    2
    3
    <h4 class="mt-3">修剪 Trim</h4>
    這是一段{{ trimMsg }}緊黏的文字
    <input type="text" class="form-control" v-model.trim="trimMsg">

參考資料:
重新認識 Vue.js | Kuro Hsu