# 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 可以隨意拖曳套件