0%

常常看到 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

動態屬性綁定(注意大小寫)

  • 宣告變數dynamic,將 dynamic 綁定於點擊事件上 :click="dynamic = dynamic === 'disabled' ? 'readonly':'disabled'"
    • 如果變數結果是 disable 的話就會切換成 readonly,反之,就會切換為 disabled
  • 接著可以將值動態地加入 HTML 屬性上 :[dynamic]
    • 綁定後,就會發現輸入框隨著切換,有不同效果
      1
      2
      3
      4
      5
      <h3>動態屬性綁定(注意大小寫)</h3>
      <button type="button"
      v-on:click="dynamic = dynamic === 'disabled' ? 'readonly':'disabled'">切換為 {{ dynamic }}</button>
      <br>
      <input type="text" :[dynamic] :value="name">
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      //JS

      Vue.createApp({

      data(){
      return {
      dynamic: 'disabled',
      breakfastShop: {
      name: '奇蹟早餐',
      imgUrl: 'https://images.unsplash.com/photo-1600182610361-4b4d664e07b9?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=200&q=80',
      resizeImg: 'https://images.unsplash.com/photo-1600182610361-4b4d664e07b9?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&q=80'
      },
      }
      }
      }).mount('#app')

readony:可以選擇輸入框,但無法輸入值
disabled:無法點選輸入框

1
2
3
4
再次補充說明:
1. dynamic = 【這邊是最前面的變數,用來存放後面回傳回來的值】
2. dynamic === 'disabled' ? 【這邊就是中間判斷式的部分,判斷 dynamic 變數是否為 'disabled'】
3. 'readonly':'disabled' 【這邊就是最後面的值,會依照前方的判斷式來決定回傳 'readonly' 還是 'disabled',如果判斷式結果為 True 則回傳 'readonly' ,反之回傳 'disabled'】

HTML 樣式綁定

樣式綁定是時常使用到的效果,能透過此方式,使顏色改變、增加一點簡易動畫的效果。

範例解說

  • 替 box 增加旋轉效果
  • 綁定class可以用陣列方式、或物件方式來添加,以下範例為物件方式
    • 物件key值對應 className,物件的值是對應 true\false(判斷式)
    • 若className 有 - , 注意要 “bg-danger”
  • 事件的綁定 change() 透過函式來切換 true\falsethis[key] = !this[key];
  • 切換是否旋轉、切換背景色
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    <style>
    .box {
    background-color: var(--bs-light);
    border: 1px solid var(--bs-gray);
    width: 80px;
    height: 80px;
    }
    .box {
    transition: all .5s;
    }
    .box.rotate {
    transform: rotate(45deg)
    }
    </style>

    <h2>切換 Class</h2>
    <h3>物件寫法</h3>
    <!-- 物件key值對應 className,物件的值是對應 true\false -->
    <div class="box" :class="{ rotate: isTransform ,'bg-danger':boxColor}"></div>
    <hr>
    <button class="btn btn-outline-primary" v-on:click="change('isTransform')">選轉物件</button>
    <button class="btn btn-outline-primary ms-1" v-on:click="change('boxColor')">切換色彩</button>

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    const App = {
    data() {
    return {
    isTransform: true,
    boxColor: false,


    };
    },
    methods: {
    change: function (key) {
    this[key] = !this[key];
    },
    addClass(arr) {
    this.arrayClass.push(...arr);
    }
    },
    };

    Vue.createApp(App).mount('#app');

整合為一個物件

將上個範例的兩個class樣式,整合成一個物件

1
2
3
4
<hr class="mt-4">
<h3>物件寫法 2</h5>
<div class="box" :class='classObj'></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
const App = {
data() {
return {
isTransform: true,
boxColor: false,

classObj:{
rotata: true,
"bg-danger": true,
}

};
},
methods: {
change: function (key) {
this[key] = !this[key];
},
addClass(arr) {
this.arrayClass.push(...arr);
}
},
};

Vue.createApp(App).mount('#app');

綁定樣式,陣列寫法

  • 針對單一元素,加入多個class
    • 此方式就不用 true\false 的判斷動作,只要綁定在陣列之中的樣式,就會套入效果
    • 像是範例,就是使按鈕背景色彩為紅色(‘btn-danger’)、無法點擊(‘disabled’)
      1
      2
      3
      4
      <h4>陣列寫法</h4>
      <button class="btn" :class="['disabled','btn-danger']">請操作本元件</button>
      <button type="button" class="btn btn-outline-primary" v-on:click="addClass(['btn-primary', 'active'])">為陣列加入
      Class</button>
  • 另一種,製作陣列,並將陣列放入
    • 將arrayClass,綁定在標籤的class上
    • 在點擊按鈕,綁定點擊事件,addClass(arr),在該函式傳入參數,將陣列內容加入arrayClass,並套入綁定的標籤上
    • 相對應的方法:
1
2
3
4
5
<h4>陣列寫法</h4>
<button class="btn" :class="arrayClass" >請操作本元件</button>
<button type="button"
class="btn btn-outline-primary"
v-on:click="addClass(['btn-primary', 'active'])">為陣列加入 Class</button>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const App = {
data() {
return {
// Array 操作
arrayClass: [''],
};
},
methods: {

addClass(arr) {
this.arrayClass.push(...arr);
}
},
};

Vue.createApp(App).mount('#app');

  • btn-primary:背景色為綠色

補充:混合寫法

  • 將bootstrap的class放入,且加入arrayClass
    • :class="[arrayClass,'text-danger'],也就是除了放入 arrayClass 這個變數之外,我們還可以放入新的class給予不同樣式
      1
      2
      3
      4
      <h4>陣列寫法</h4>
      <button class="btn" :class="[arrayClass,'text-danger']">請操作本元件</button>
      <button type="button" class="btn btn-outline-primary" v-on:click="addClass(['btn-primary', 'active'])">為陣列加入
      Class</button>

行內樣式style

要綁定style的時候

  • key會帶入style的屬性(注意要以駝峰式),如background-color,要改為backgroundColor
  • 值則是帶入style相對應的值
1
2
3
4
5
<h2>行內樣式</h2>
<h4>綁定行內樣式</h4>
<div class="box" :style="{backgroundColor:'red'}"></div>
<div class="box"></div>
<div class="box"></div>

加入準備好的資料格式

  • 將設定好的物件,裡面有包含數個樣式,直接綁定至style

  • 背景色彩,紅色,邊框5px

同時多個樣式

  • 以陣列裡面包多個物件
    1
    <div class="box" :style="[styleObject,styleObject2]"></div>

  • 建立add、minus兩個按鈕
    • 點選add增加數字、點選minus減少數字
  • 讓add按鈕綁定addFn函式:v-on:click="addFn" on click事件,執行addFn函式
  • 綁定後,在methods撰寫addFn函式內容,要取得 data 中的 num 才能進行運算 =>this.num++
  • 同理,在minus的按鈕,函式內運算this.num++,並將點擊事件放入button
    • v-on:Event 事件綁定,有兩種撰寫方式
1
2
3
4
5
6
7
8
<div id="app">
<h1>{{num}}</h1>

<button v-on:click="addFn">Add</button>
<!-- v-on 改為@ -->
<button @click="MinusFun">Minus</button>

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

data(){
return {
num: 0
}
},
methods: {
addFn() {
//num.value = num.value + 1;
this.num ++;
},
MinusFun(){
this.num--;
},
}
}).mount('#app')

codepen

事件與class的綁定

  • 於 box 綁定旋轉的效果 :class="{ rotate: isTransform }
  • 在button綁定觸發旋轉的事件
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    <style>
    .box {
    margin:0 auto;
    background-color: #fff;
    border: 1px solid #ccc;
    width: 80px;
    height: 80px;
    }
    .box {
    transition: all .5s;
    }
    .box.rotate {
    transform: rotate(45deg)
    }
    </style>
    <div id="app">
    <h3>觸發事件 與 縮寫*</h3>
    <div class="box" :class="{ rotate: isTransform }"></div>
    <hr>
    <button class="btn btn-outline-primary" @click="changeClass" >選轉物件</button>
    </div>
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    Vue.createApp({

    data() {
    return {

    isTransform: true,
    };
    },
    methods: {
    changeClass() {
    this.isTransform =!this.isTransform;
    },
    }
    };

    }).mount('#app')

帶入參數

  • 建立 change() 函式以帶入參數方式,來變化 isTransform 的 true\false
    1
    2
    3
    <h3>帶入參數*</h3>
    <div class="box" :class="{ rotate: isTransform }"></div>
    <button class="btn btn-outline-primary" @click="change('isTransform')">選轉物件</button>
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    Vue.createApp({

    data() {
    return {

    isTransform: true,
    };
    },
    methods: {
    changeClass() {
    this.isTransform =!this.isTransform;
    },
    change(key) {
    this[key] = !this[key];
    },
    }
    };

    }).mount('#app')

    動態物件方法 {}

  • 在一個元素上,加入多個事件
  • 注意:此方式無法傳入參數
    1
    2
    3
    4
    5
    6
    7
    <h3>動態物件方法 {}</h3>
    <!-- 此方法無法傳入參數 -->
    <button class="box" @="{
    mousedown:down,
    mouseup:up
    }">
    </button>
    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
    Vue.createApp({

    data() {
    return {

    isTransform: true,
    };
    },
    methods: {
    changeClass() {
    this.isTransform =!this.isTransform;
    },
    change(key) {
    this[key] = !this[key];
    },
    down() {
    console.log("按下");
    },
    up() {
    console.log("放開");
    }
    }
    };

    }).mount('#app')

codepen

屬性綁定可以輕鬆的將data中的資料,與HTML的標籤屬性綁定,這樣一來可以動態的變更資料。

原本 HTML 的樣子

  • img中原本有個圖片資料
  • v-bind是指令,後接的是HTML的屬性
1
2
3
<h3>綁定屬性 v-bind</h3>
<p>{{ breakfastShop.name }}</p>
<img src="https://images.unsplash.com/photo-1600182610361-4b4d664e07b9?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=200&q=80" class="square-img" alt="">
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//JS

Vue.createApp({

data(){
return {
breakfastShop: {
name: '奇蹟早餐',
imgUrl: 'https://images.unsplash.com/photo-1600182610361-4b4d664e07b9?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=200&q=80',
resizeImg: 'https://images.unsplash.com/photo-1600182610361-4b4d664e07b9?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&q=80'
},
}
}
}).mount('#app')

修改 => 綁定JS中 breakfastShop 物件資料內容

  • 將原本src => v-bind:src="breakfastShop.imgUrl"
    • 此外title 屬性,也能照樣綁定喔!
      1
      2
      3
      <h3>綁定屬性 v-bind</h3>
      <p>{{ breakfastShop.name }}</p>
      <img v-bind:src="breakfastShop.imgUrl" class="square-img" v-bind:title="breakfastShop.name" alt="">

縮寫形式

  • 留下冒號
    1
    2
    3
    <h3>縮寫形式 <code>:</code></h3>
    <img :src="breakfastShop.imgUrl" class="square-img" :title="breakfastShop.name" alt="">

其他屬性的綁定

  • 當他是飽的狀態,就無法按下送出
    • 預設是false 所以可以送出表單
    • 但當點擊狀態切換(isFull: true),此時就會無法點擊送出按鈕
  • 由範例可得知,可以透過 true\false 的狀態切換,製造出不同互動效果
    1
    2
    3
    4
    5
    6
    7
    8
    <h3>更多屬性綁定</h3>
    小明還想點餐:
    <form action="">
    <input type="text" value="我要吃蘿蔔糕">
    <button type="submit" :disabled="isFull">送出</button>
    </form>

    <button type="button" v-on:click="change('isFull')">狀態切換</button>

  • 預設是false,所以可以點擊送出

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