# 第二週|筆記 by Sz
###### tags: `Sz` `week2` `Vue新手夏令營`
- [Vue 新手夏令營 課程頁面:內含本週作業](https://hackmd.io/@dbFY0UD9SUeKmNXhWf01ew/BkJoW-hn_/%2FC05go-8iTSS-nrMwKU22kA)
- [:sun_with_face:筆記入口](/2JiZbCPdR0G4p5fNycPmTg)
- [本週範例程式碼](https://github.com/hexschool/summer-camp-vue3/blob/master/week1/data.js)
- [來自天使的筆記(用力參考)](https://hackmd.io/@WangShuan/HyexbUhaO)
# 課前知識
不弄懂存活率不樂觀喔
- [需要知道的語法糖|筆記 by Sz](/1X5juhqDRmaeefUHD0NAKQ)
- [this 到底是誰|筆記 by Sz](/Ngdg5j1RTDy5l__Sa-UTqQ)
- [物件傳參考|筆記 by Sz](/1UjaEO00RDeSkoSDbbNPWg)
- [基礎的 Promise|筆記 by Sz](/ISgWv-n_Qbmvf6Qv3Ow7qQ)
- [用 axios 串接 API|筆記 by Sz](/K3goXk3BSDqehj1G88rjJw)
- [在瀏覽器運行 ES 模組|筆記 by Sz](/wG78GzzdR66WhFsWU2UcPA)
- [現行的 ES 模組使用技巧|筆記 by Sz](/MsqxGtNPS4i4YjZtcZDaiw)
## 與 jQuery 的差別(選讀)
```htmlembedded=
<!-- 記得要匯入 cdn -->
<div id="text"></div>
```
```javascript=
const personText = '我是卡斯伯';
$(document).ready(function() {
$('#text') // 取得 DOM 元素
.text(personText) // 寫入值
$('#num').on('change', function() { // 監聽
console.log($(this) // this 取得 DOM 元素
.val()); // 取得值
})
})
```
### jQery 風格
1. 資料
2. 操作 DOM
3. 取值
### 三大框架(Angular, Vue, React)則是
* 關注點分離
* 資料可以直接對應畫面
## Vue 的初始化
### Vue 的起手式
#### data:資料邏輯 function
- `return` 的內容是一個 `object`
- 透過 `v-text`(`{{key}}`),顯示於畫面
#### methods:方法 object
內部包含較多行的 function
#### mounted: 生命週期 function
### 畫面
```htmlembedded=
<div id="app"> // .mount('#app') 指定要在這生成(看下段)
</div>
```
### JS
```javascript=
Vue.createApp({ // 導入一個物件(vue 起手式)
data: function() { // function
return {
};
},
methods: { // object
},
mounted: function() { // function
}
}) .mount('#app') // 雙向綁定
```
### 實例
```htmlembedded=
<div id="app">
<!-- 把 data 抓到畫面 -->
{{ text }} // string
{{ name }} // 小明
{{ num }} // 0
{{ person.name }} // 小白
<!-- 把畫面抓回 data:指令 (v-) -->
<input type="number" v-model="num">
</div>
```
```htmlembedded=
<script>
Vue.createApp({ // 導入一個物件
data: function() { // function
return {
text: 'string',
name: '小明',
num: 0
person: {
name: '小白',
image: '圖片網址',
gender: 'male',
cash: 1000
},
people: [
{
name: '小明',
image: '圖網址',
gender: 'male',
}.....
]
};
},
methods: { // object
},
mounted: function() { // function
// ajax 的資料會放這
}
}) .mount('#app') // 雙向綁定
</script>
```
## data -> 畫面|`v-text` (簡寫`{{}}`)
在 mount 到的畫面區塊內(`#app`)寫入 `{{ 該 data 名稱 }}`
```htmlembedded=
<p>{{ text }}</p> // string
```
## 畫面 -> data|`v-model`
:::warning
`v-` 為 vue 語法的開頭!
:::
`v-model` 用於資料的雙向綁定,這個 `input` 就會綁定到 `data` 上的 `num` 了
```htmlembedded=
<input type="number" v-model="num">
```
## data -> HTML 標籤的屬性|`v-bind` 動態屬性
事前知識:點記法、括弧記法(有機會再補上)
1. 如果屬性內只包含 `data` 來的內容
在 `""` 內輸入即可
```htmlembedded=
<img :src="person.image" :alt="person.name">
```
2.如果是包含非 `data` 內容,
在 `""` 內,記得要使用樣板字面值
```htmlembedded=
<a :herf="`mailto:${ item.email }`" :alt="">
```
## 判定|`v-if`, `v-else`, `v-else-if`
判斷如果 gender 為 male,就顯示一張 male 的 icon
非則顯示 female 的 icon
```htmlembedded=
<!-- 省略 cdn 的部份 -->
<i v-if="person.gender === 'male'">male icon</i>
<i v-else">female icon</i>
```
如果中間有更多判斷:
```htmlembedded=
<i v-else-if">female icon</i>
```
## 資料的迴圈| v-for
data 的資料批次加到畫面
很像 `forEach()`
也可以帶物件
:::warning
以下 `:key` 到下週會再講解,`v-for` 就會需要帶 `:key`
:::
```htmlembedded=
<ul>
<!-- item 代表每個獨立的物件(people[item]) -->
<li v-for="item in people" :key="item.id">
{{ item.name }}
<img :src="item.image" alt="">
<i v-if="item.gender === 'male'">male icon</i>
<i v-else="item.gender === 'female'">female icon</i>
</li>
</ul>
```
```javascript=
data: {
people: [ // 有很多 object
{
name: '小明',
image: '圖網址',
gender: 'male',
},...
]
}
```
## 事件觸發|`v-on`(簡寫`@`)
### 點擊的監聽|`@click`
互動性的標籤,需要設定監聽 method
```htmlembedded=
<!-- 這裡有 -->
{{ person.cash }}
<button type="button"
@click="person.cash++"> // function 放 @click
增加</button>
<!-- 下週預告:跟傳值有關 -->
<button type="button"
@click="plusCash(item)">
增加</button>
```
```javascript=
// 下週預告
plusCash() {
item.num++;
}
```
## methods
如上方,第一個 `@click`,只有一行可以直接寫在 HTML
methods 內就會放置較複雜的 methods(兩行以上)
## Vue 的取值:this
用 this 去呼叫 data 或 methods
```javascript=
mounted: function() {
console.log(this.text);
}
```
## ES module
> [ESM Module](https://cdnjs.com/libraries/vue)
初學可以先整包 Vue 載下來
後面會開始用到模組化,就不會整包帶下來了
載入 Vue.js ESModule
- createApp
- ref
- reactive
- ....
```htmlembedded=
<script type="module">
import { creatApp } from 'https://cdnjs.cloudflare.com/ajax/libs/vue/3.1.4/vue.esm-browser.min.js'
</script>
```
## 其他補充
- [Bootstrap Icon](https://icons.getbootstrap.com/)
- 排版輔助 ESlint