# 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`