# 1. Vue 基礎
#### 11/29
1. Mode:開發環境 vs 生產環境 (唐綺陽事件)
2. Vue.js devtools 開發擴充功能:只能用 live server 才偵測的到
3. 模板語法 {{ text }}:兩個大括號功能類似 innerText 或 jq 的 .text
- 如果是 {{ html }},data 的 html 變數放 html 會視為文字渲染出來,需要使用 v-html,但需注意標籤內的東西會被蓋過
4. v-if 判斷式:若條件不符合則不會出現在 DOM 上;和 v-show (非常少用)的差別則是 v-show 條件不符合時會在 DOM 上 display:none
5. 只要是 v- 開頭的屬性,如 v-xxx="yyy",引號內的值皆是 js 的範圍
6. 迴圈: v-for="value in 陣列" 、 v-for="(value, index) in 陣列"、v-for="n in 數字"
### 屬性綁定
- v-bind:href="xxx",簡寫為 :href="xxx",圖片來源 :src。注意只有 style、class、value 屬性綁定的寫法不同,後面的值為 json 物件 {}。
- :style="{ color: 'red', backgroundColor: 'black' }",值裡面是放 json 物件 {},因為值裡面是 js 的範圍,所以物件內的 value 為字串,'red' 需要引號,key 使用駝峰式。
- :class="{ class名: 布林 }"
- 表單 `v-model`
- 如果是綁定使用者輸入的字,如 input:text,我們使用 v-model 而不是綁定 :value,:value 是代表那個欄位的值
- :value 用法出現在 input:button 或 select/option (下拉選單) 的 option (搭配 v-model 放在 select) 或其他...
```
<select v-model="form.select">
<option v-for="fruit in fruits" :value="fruit">{{ fruit }}</option>
</select>
```
- vue 具有雙向綁定特性,也就是 MVVM 的便利性。當 v-model 內的文字改變,data 內的資料跟著改變,如果有在別的標籤使用 {{ form.text }},那此標籤的內文也會跟著改變!
- input:checkbox & input:radio 以 v-model 區分群組(即擁有原本的 name 屬性),且 v-model 是使用者選 or 輸入的值,而 :value 是欄位的值
- //! 靠北老師這邊 select/option 和 radio 的 :value 根本沒卵用,沒顯示出欄位的值阿!
- //! 不你錯了,試試將 :value="fruit" 的值更改或整個 :value 拿掉,F12 檢查 Vue 的 data 變化並操作看看~
### 事件
- 本身預設有 event 物件 (事件的物件),要用再代就好
- 也可以代 參數
- 如果要代 參數 也要 event 物件,使用 $event 為固定寫法
```js
... v-on:click="clickBtn"
... @click="clickBtn2"
... @click="clickBtn('hi')"
... @click="clickBtn('hi', $event)"
...
methods: {
clickBtn () {
alert('點')
},
clickBtn2 (event) {
console.log(event)
alert('點')
},
clickBtn3 (text) {
alert(text)
},
clickBtn4 (text, event) {
console.log(event)
alert(text)
},
...
}
```
- @click.prevent = .preventDefault() 阻止預設事件(像是讓 a 連結不跳頁);.stop = .stopPropagation() 阻止事件冒泡
[文章](https://ithelp.ithome.com.tw/articles/10198999 "[筆記][JavaScript]所謂的「停止事件」到底是怎麼一回事?")
- 補充 input:text 可以加上 @keydown. + 按鍵名稱,如 @keydown.enter="xxx",接著給 v-model="form.text",在 methods 抓 data,接著須注意 (1) 在 methods 抓 data 時要加 `this` (2) 在 methods 呼叫另一個 method 也要加 `this`
---
### computed
- 經過 function 運算產生的 data(所以它算是 data!)
- 一定要 return
- 先記得只能讀(read only 唯讀),不能改,不能用 methods 改它,之後會再教怎麼改
- 運作邏輯:只要 function 內有用到的 data 有變動時,computed 就會重新跑一次 function,算出目前的值是什麼
- 相較於同樣是 function 的 methods:methods 是做動作;computed 是可以平常使用的值
- 延伸使用:陣列的搜尋,對 data 陣列做 filter,return 一個 filter 過後的陣列,可以寫一個搜尋框,根據你輸入的字去做 filter
- 所以 computed 可以當作 data 去使用,而 methods 也可以加上 return 當作 data 去使用,但不建議這麼做,因為它就是一般的 function,而 computed 就是 data。主要差別就是計算的時機,可以看 [文章](https://yuhantaiwan.coderbridge.io/2020/05/17/Vue%E5%AD%B8%E7%BF%92%E6%97%85%E7%A8%8BMile11-Computed%E8%A8%88%E7%AE%97%E5%B1%AC%E6%80%A7%E7%AF%87/ "Vue.js 學習旅程Mile 11 – Computed 計算屬性篇")
### watch
- 偵測 data 變更
- 以 data 名當作 function 名
- 如果是陣列或物件,需要做深層監聽,不過須注意 deep: true 時 newValue 會等於 oldValue,所以會無法看到舊值,只會偵測到變更。
```js
// 省略
form: {
deep: true,
handler (newValue, oldValue) {
console.log(newValue, oldValue)
}
}
```
### 生命週期
- created、mounted、destroyed,前兩個較常用,寫在和 data 同級。
- 使用 $refs 或 $el 抓取元素,位置必須在 mounted 之後,如果是在 created 使用或 mounted 之前會 undefined 或 null。
- 也可以放在 methods 或 computed 內使用,但要注意 function 使用的時機點是否在 mounted 之後,否則會抓不到東西。
- $el 不能用 getElementById 抓取,要用 querySelector 或 querySelectorAll。
- 比較少用這個去抓,因為 data 就可以綁定。可能會用到的是 canvas,例如之前使用的 chart.js,抓到元素後用 getContext 2d。
- 在使用 localStorage 時會使用到 mounted。
### 練習筆記
- map 的用法
- 回傳新陣列
```
okAll (value) {
this.items = this.items.map(item => {
item.ok = value // 複習JS基礎: 右邊可以放判斷式
return item
})
}
```
- computed 的用法
- 計算輸入框內的字數,改變邊框顏色
- filter 的用法
- 使用 input:text 製作一個 v-model='search' 輸入框
- 以下之後,用 filteredFoods 跑迴圈即可
- 進階: filter 後刪除新陣列的選項,這時候 push 前要先給每個人 id
```
computed: {
filteredFoods () {
return this.foods.filter(food => {
return food.name.includes(this.search)
})
}
}
```
- watch (監聽) 並存入及讀取 localStorage 的用法。
- deep: true
```
watch: {
items: {
deep: true,
handler (value) {
localStorage.setItem('list', JSON.stringify(value))
}
}
},
mounted () {
<!-- getItem 抓出來是文字所以要用 JSON.parse -->
<!-- 因 localStorage 沒有值會是 null -->
<!-- 所以這邊用短路求值 || [],就能省一個 if -->
this.items = JSON.parse(localStorage.getItem('list')) || []
}
```
---
#### 11/30
### component
- 元件名稱做為標籤名稱。
- 使用標籤屬性將資料傳入元件;標籤沒有冒號":"就是寫死,有冒號就是綁定,即是把 data 和傳入的資料綁在一起。
- 單向綁定。
- 如何內層改外層(進階:內層不同步),第一種方法是自訂事件,第二種為.sync(Vue語法糖)
- 大多時候是使用別人的元件,較少自己寫但還是會寫到。
###### tags: `Vue`