# W_VUE3 官方影片筆記
## 目前理解
- vue主要再做串接,就像電話通訊或是插上電源線讓js與html彼此互通
- vue很像tailWind,簡單來說就是js的 inline style
- data()
- 提供界面新用,應用需要根據資料動態更新界面
- method()
- 提供使用者互動的方法,而呈現內容會是data()做的是,比如數字相加在這,而結果在data()
- computed
- 目前已知可以將data裡的值融合作用,比方data裡面建立了a和b,如果想要摻在一起就用computed
- watch()
- 監聽作用,可以用來判斷當事情發生時,就會作出相對應的動作
- 根據家銘描述,切換語言時,可以監聽特定一塊區域,畫面不會重新loading
## 基礎功能
要做vue串接,先在vue加上這段
```javascript=
//# 次處為options object 雖然教options 卻不能都是空值,至少要一個空物件
//# 這樣會新增一個instance實例,而html裡面得id=app就會被它連接
const app = Vue.createApp({
data() {
return {
product: "socks",
};
},
});
```
html可以這樣
```html=
<!-- {{}}資叫做鬍子 裡面放得東西是透過vue連接 -->
<!-- 有點像是電話得概念,串街過去 -->
<!-- 裡面只能放資料,和表達式 -->
<div class="product-intro">
<h1>{{ product }}</h1>
</div>
```
## v-bind
現在js裡面給抓取物件取名(EX:image)並放入圖片檔案位置
```javascript=
const app = Vue.createApp({
data() {
return {
product: "socks",
image: "../Intro-to-Vue-3/assets/images/socks_green.jpg",
};
},
});
```
然後在html裡面要擷取的圖寫上下方call就會偵測到圖片了
```html=
<!-- v-bind: 為關鍵字 -->
<img v-bind:src="image" />
<!-- 省略也行 -->
<img :src="image" />
```
v-bind有很多可使用得地方,舉例
- div class
- a href
- span style
- etc
## v-if v-else
- 主要是偵測js裡面設定得布林值決定顯示在頁面得值,如果只要寫if也是可以,只是寫false的話,內容會直接消失
- 也可以做else if 判斷
```html=
<p v-if="inventory >10">In Stock</p>
<p v-else-if="inventory <= 10 && inventory > 0">Almost out of stock</p>
<p v-else="inStock">Out of Stock</p>
```
```javascript=
const app = Vue.createApp({
data() {
return {
product: "socks",
image: "../Intro-to-Vue-3/assets/images/socks_green.jpg",
// inStock: false,
inventory: 0,
};
},
});
```
## v-show
判斷布林值,如果是true,內容會顯示,如果是false,內容會消失,但其實它偷偷得在瀏覽器上下inline style 隱藏(可以從inspet裡面看到)
## List Rendering
### v-for
```javascript=
//detail is alias or element
//details is what we want to loop for
//{{}}裏面放detail(detail is alias or element
)
<li v-for="detail in details">{{ detail }}</li>
```
這段裏面 `details` 代表在 vue app 創建的屬性
```javascript=
const app = Vue.createApp({
data() {
return {
product: "socks",
image: "../Intro-to-Vue-3/assets/images/socks_green.jpg",
inventory: 0,
//v-for details 連接到此
details: ["50% happy", "30% jeremy", "20% watson"],
variants: [
{ id: 2234, color: "green" },
{ id: 2235, color: "blue" },
],
};
},
});
```
這段的`:key="variant.id` 目前已知是追蹤作用,這會給每個DOM元素一個唯一的key,這樣Vue 可以綁定element 而當有東西更新也不會放棄追蹤
```javascript=
<div v-for="variant in variants" :key="variant.id">{{ variant.color }}</div>
```
## Event Handling
這次主題探討addEventListener,在 vue 表現是 v-on:click="value"
```html=
<!-- 用vue的方式,直接設定值的運作 -->
<button class="button" v-on:click="cart += 1">add to Cart</button>
<!-- 用vue方式,值是method -->
<button class="button" v-on:click="addToCart">add to Cart</button>
<!-- 用vue簡寫方法 -->
<button class="button" @click="addToCart">add to Cart</button>
```
在const app = Vue.createApp 新增 methods:{}
```javascript=
methods: {
addToCart() {
this.cart += 1;
},
updateImage(variantImage) {
this.image = variantImage;
},
},
```
method 可以搭配前面 v-for ,建立在hover文字的時候同時變換圖片
```javascript=
//增加了@mouseover
//並且建立updateImage方法
//參數爲variants裏面的物件屬性,
<div v-for="variant in variants" :key="variant.id" @mouseover="updateImage(variant.image)">{{ variant.color }}</div>
//在vue.createApp裏面的variants建立image 這主要是當滑鼠晃過文字就會變更圖片
variants: [
{ id: 2234, color: "green", image: "../Intro-to-Vue-3/assets/images/socks_green.jpg" },
{ id: 2235, color: "blue", image: "../Intro-to-Vue-3/assets/images/socks_blue.jpg" },
],
```
## Class & Style Binding
這篇主要講解加上style 還有 class命名等
```javascript=
class="color-circle"
//也可以寫成:style="backgruond-Color: variant.color"
:style="backgruondColor: variant.color"
//上面這段當hover到指定屬性,會轉譯為 backgruond-Color: color
```
---
style 其實也可以寫成以下這樣
```html=
這會連接到 vue.createApp 裡自己所設定的data
<div style="styles"></div>
```
```javascript=
data(){
return{
styles:{
color:"red",
fontSize:"14px"
}
}
}
```
---
當產品銷售完畢,希望可以取消點擊 cart 的效果
```html=
<!-- 這段連接到 css 裡面得屬性,並且在附上 !inStock -->
:class="{disabledButton: !inStock}"
:disabled="!inStock"
```
在vue裡可以建立多個class,第二個要寫成:class="",雖然看似建立多個class但實際是第二個class偵測的data()裡面我們自定義的屬性,並且將其合併到第一個class
```html=
<div
class="try"
:class="try:somethingFromDataMethod">
</div>
<!-- :class轉譯後 -->
<div
class="try somethingFromDataMethod" >
</div>
```
## computed Properties
computed 是可計算模版,有很多功能可以做,目前已知
- [判斷](https://play.vuejs.org/#eNp9ktFP2zAQxv+Vk19SpK6dBk9VyUQ3tA0JNm1o0jTvwSTXxJDYls/uiqL875zTtOUBeLP9fef7fWd34sK52SaiWIglFV67AIQhulwa3TrrA3TgURVBb3AKhW1dDFhCD2tvW8i4MpNGmsIaCqBiqK2H80PFpJMGwKgWF5Bd2drAZ4vZNB3eWftAC/ib1gDZ74jwAd7BRblRpuAOX6IuR+son7K8UqSLF7Qz1m5rhOtHCugfmQngnzT9SYKbz0Ed0T2u97wu3jWaaixXCeYaiVSFjL/3TiYncJ7DEMLzVLwZI84G+lmDpgo15PAePkL2BykDznljuX3qvJzvJsqz5E3A1jUqIO8Ali7/qugIMI5jOU+DZ5mcMnnXvULY93x1cqQeh3vFVATiYGtdze7JGn7SgVyKlEc36L+7oDm4FItdpqSpprH/r4az4COOQ+WaGouHF87vaZvOpPjhkdBvUIqDFpSvMOzky183uOX1QWxtGRt2vyH+RLJNTIw72yqakrGf+Qbab8PH1Ka6pcttQEP7UAk0OfvBLwX/zk9vRD/ins7Ohjp+N9E/AfLCBKY=)
- 相加
- 偵測
簡單來說,先在html建立{{}},她會偵測computed,而computed可以指定data()物件,假設data()內容改變,{{}}會透過computed在改變值內容
編寫順序 html > data() > computed
## Components & Props
這段講解可以把可個程式碼,比方 html css js 拆分開在多個檔案並且重構成同一個頁面,這要利用app component
component可以放兩個參數
- component名稱,可插入在任意html的tag
- ex:<this-is-test></this-is-test>
-
```javascript=
//product-display 依據class 寫入
app.component("product-display", {
template:
/*html*/
`
<div class="product-display">
//content
</div>
`,
data() {
return {
//connect content
],
};
},
methods: {
},
//用來計算用,相加相減
computed: {
},
});
```
/*html*/這個是關鍵字,這樣才能在 js 中置入html,並且記得加上template `html放入樣板字面符號裏面`,而`app.component('name')`,這裏的name會形成html tag標籤,所以當我要插入在html時,可以寫`<name></name>`。
props現在還有點模胡,目前依照郭嘉描述,簡單來說他就是字元件,拆出放在各處。通常是打後端api,得到資料後,在用 v-html 去接 先瞭解這樣就好
## Communicating Events
用 cart 長度去計算嘉入購物車數量
- 父元件的標籤,
- 建立cart陣列
- method 建立updateCart()並且推到cart陣列裡面
@emit 像是建立一個訊號塔,他可以發送訊號,當接收到他的tag 有作動時,
## form & v-model
這裏主要是在介紹商品評論表單設定,利用雙向綁定機制在 v-model ,首先他建立了新的 component 三個form,並且在上面綁定
```javascript=
<label for="name">Name:</label>
<input id="name" v-model="name">
<label for="review">Review:</label>
<textarea id="review" v-model="review"></textarea>
<label for="rating">Rating:</label>
<select id="rating" v-model.number="rating">
//component
data() {
return {
name: "",
review: "",
rating: null,
};
},
```
---
---
# Real World Vue 3 [v]
父的元素可傳子 只要有在tag綁定
## Vue Router Essentials
Router(路由)就是一個幫你決定「看哪個頁面」的導航員。
它會根據你點擊的連結(或網址)來決定顯示哪個內容,而不需要整個網頁重新載入。
以下兩者是一起的
`<router-link>`:像超連結,但不會刷新整個頁面。
`<router-view>`:Router 會把對應的內容塞到這裡
這題有遇到版本問題,需要降至 nvm 14 才可以跑 `npm run dev`
### 下面例子顯示import router頁面有兩種方式 home 跟 about
```javascript=
import Home from '../views/Home.vue'
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/about',
name: 'About',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () =>
import(/* webpackChunkName: "about" */ '../views/About.vue')
}
]
```
## API Calls with Axios
目前教了簡單的Axios串接方式
```javascript=
data() {
return {
events: null
}
},
//他可以去查找伺服器資料
created() {
axios
.get(
'https://my-json-server.typicode.com/Code-Pop/Real-World-Vue-3-New-Syntax/events'
)
.then(response => {
this.events = response.data
})
.catch(error => {
console.log(error)
})
}
}
```
return events:null是因爲目前在componet 有使用 v-for,有綁定 events,但這時是透過API來獲取內容,如果沒有API,那events就是undefind,這樣彙報錯,所以先預設她是null
當建立了 Axios,就會創造實例,會全部綁定在同一個proto,就會造成混亂不好操作,難以debug,所以作者建立了一個當案管理夾EventsServe.js,建立完後在import進Evenlist.vue裡面
## Dynamic Routing
在json api文件中,id就是router的聯結,所以假設前面`https://xxxxx/event`
id是123
```javascript=
{
"id": 123,
"category": "animal welfare",
"title": "Cat Adoption Day",
"description": "Find your new feline friend at this event.",
"location": "Meow Town",
"date": "January 28, 2022",
"time": "12:00",
"organizer": "Kat Laydee"
}
```
那`https://xxxxx/event/123`就會聯結到123的資料
### **Vue 3 `import` 路徑差異總結**
| **比較項目** | **相對路徑 (`../`)** | **絕對路徑 (`@/`)** |
|----------------|--------------------------------|--------------------------------|
| **寫法範例** | `import Home from '../views/Home.vue'` | `import Home from '@/views/Home.vue'` |
| **參考位置** | 依照目前檔案所在目錄,使用 `../` 回溯 | `@` 直接對應到 `src/` |
| **管理難度** | 層級深時,路徑變長且不易閱讀 | 簡潔明瞭,方便管理 |
| **檔案移動影響** | 需要修改 `import` | 不受影響,路徑固定 |
| **設定方式** | 無須額外設定 | 需在 `vite.config.js` 或 Webpack 設定 `alias` |
| **適用場景** | 小型專案、層級淺的檔案 | 大型專案、常移動檔案的情境 |
| **優缺點** | ✅ 無需額外設定 <br> ❌ 路徑可能變得冗長、難以維護 | ✅ 易讀性高,專案結構清晰 <br> ✅ 檔案移動不影響 `import` <br> ❌ 需要手動設定 `alias` |
### **📌 建議**
👉 **小型專案** 可使用 `../`,但層級一深就會變亂。
👉 **大型專案** 統一使用 `@/`,讓 `import` 更直觀,不怕檔案移動影響。
### router-link to
to 是類似 a href的產物,他可以讓頁面不必刷新的情況下跳轉
### 觀念
作者提到,因爲router目前是hardCode 所以點擊任何卡片都會連接到router 123,只有改成動態才有可能解決這個辦法
做法很簡單
---
# Vue 起始
## 掛載 DOM
需要先建立 Vue.js 實例,才可以對 DOM 進行編輯。
```javascript=
//此狀態為 Vue3 掛載,利用 mount,並且指定 DOM 節點
const vm = Vue.createApp({
// options
});
vm.mount('#app');
```
## 關於 data 污染
這裡涉及到淺拷貝與深拷貝
- 假設只是單純一個物件,裡面無巢狀可以不必擔心此問題,只需要使用{...preamter}就可以淺拷貝
- 如果物件出現巢狀,這問題就要小心,需要使用深拷貝方法
- JSON.parse(JSON.stringify(...))
- cloneDeep
- 如果資料不小心被改掉了,有幾招可以使用
- 備份還原法:將資料事先被份,所以獲取到後就要先 cloneDeep
- 重新獲取資料:重新打一次API
- 狀態管理:使用 Vuex 等等
## computed 好處
雖然 method 跟它很像,但是他是使用快取的方式暫存,不會重新 run 一次程式,節省效能,加快渲染
## Watch
簡單來說就是偵測到指定ref內容變更後,便開始展開動作
## 其他
autoResize() 是文字自適應textarea套件
vue dragble 是vue 可以隨意拖曳套件