--- tags: Vue.js --- # Vue Composition API ## 你需要先知道的事 Composition API 是 vue3 開發出來的另外一種撰寫方法。 其好處是: 1. `setup()` 方法中沒有 `this` 2. `setup()` 方法中可以只 `return` 實例需要用到的屬性 3. 沒有命名衝突問題 4. 其編譯後的程式碼更容易壓縮 另外建議使用 Composition API 都用 ESM 方式引入不要用 CDN 整包引入(ESM 跟 CDN 一次只選用一種,不要兩種都用) 在 `Composition API` 中 `data` `methods` `mounted` 都會捨棄,改寫成一個 `setup(){ return {}; }` ## 撰寫方式 創建一個 `html` 檔 並在 `body` 標籤中創建 `div#app` 在 `body` 最下面寫 `script` 代碼 首先使用 `ESM` 方式引入 `vue` 中的 `createApp` 接下來使用 `const` 聲明 `app` 為一個物件 物件中放入一個 `setup` 的函數 在裡面撰寫程式碼 最後通過 `app.mount('#app')` 創建整個 `vue` 實例 整個示例主要的 script 代碼如下: ```javascript= import { createApp, ref } from "https://cdnjs.cloudflare.com/ajax/libs/vue/3.0.11/vue.esm-browser.js"; const app = createApp({ setup() { const text = ref('Hello World'); // 這裡等同於 data const changeText = () => { // 這裡等同於 methods text.value = 'Hello Vue'; } return { // 宣告完後要用 return 才會渲染 text, changeText } } }) app.mount('#app'); ``` ## `ref` vs `reactive` - ref 可用於變數物件或陣列等,總之就是不限型別,其內部還是調用 reactive - reactive 只能用於物件,建議把有關聯的數據放在同一個對象裏提高代碼的可讀性(不熟的話先不要用,reactive 很多雷點) - reactive 如果被解構賦值的話,裏面的東西會失去雙向綁定的特性,此時可以通過 toRefs 把物件裏面的每個屬性轉成 ref 來延續使用 - ref 定義的東西一定要用 .value 才可監控與獲取哦(多了 .value 就不會覆蓋到原始實體,相對來說會比較穩定) - 了解更多請參考以下關鍵字:Proxy、getter、setter、defineproperty - ref 用於物件時 在存取屬性也要加上 `.value` (EX: `person.value.name` .value 要放在物件的後面&屬性前面 小寫別寫錯喔) - 建議初學者都是一路 const + ref 把 data 宣告到底(畢竟有雷別踩R~) - 建議使用 const 是要避免覆蓋,因為常數不能重新賦值(會報錯) ## `watch` vs `computed` `vue` 中的 `watch` `computed` 可以單獨被拿出來使用 提取方法同上面的 `ref` 相同 直接通過解構方式即可(就是 `import { watch, computed } from "vue ESM URL";` 這樣) 在 `setup` 中要使用 `watch` `computed` 不需要像 `ref` `reactive` 一樣通過 `const` 定義 只需要直接寫 `watch()` `computed()` 即可,不過跟原本在 `vue` 實例中的寫法也稍有不同 首先 `watch` 的參數1 為 要監控的資料 `dataName` * 當要監控的資料為陣列或物件中的單一值 為了減輕效能 可以不需要把整個陣列或物件傳入 改成使用箭頭函式 `return` 該單一值 - 這裏 `return` 可以讓它繼續被監控 * 需注意 若沒有使用 `return` 則該值就只是一個字符串 跟 `vue` 不會有任何綁定關係 參數2 為一個 `callback`,在 `callback` 中則一樣有 `newV` 與 `oldV` 這邊我們定義一個要監控的資料並把其傳入 `watch` 的參數1 再通過 `v-on` 更改其值 就會執行 `watch` 中的回調函數了 代碼如下: ```javascript= import { createApp, ref, watch } from "https://cdnjs.cloudflare.com/ajax/libs/vue/3.0.11/vue.esm-browser.js"; const app = createApp({ setup(){ const isShow = ref(false) const formData = reactive({ name:'', age:10 }) const changeData = () => { isShow.value = !isShow.value formData.age = 19 } watch(isShow, (newV,oldV) => { console.log(newV, oldV) }) // 監控物件中的單一值 watch(() => formData.age, ( newV, oldV ) => { console.log(newV, oldV) }) return { isShow, changeData } } }) app.mount('#app') ``` `computed` 寫法就跟原本差不多 只需注意若要計算的值是用 ref 定義的 需加上 `.value` ```javascript= import { createApp, ref, watch, computed } from "https://cdnjs.cloudflare.com/ajax/libs/vue/3.0.11/vue.esm-browser.js"; const app = createApp({ setup(){ const num = ref(1) const dblNum = computed(() => { return num.value * 2 }) return { num, dblNum } } }) app.mount('#app') ``` ## `mounted` mounted 在 Composition API 中要改寫成 onMounted 同一個 setup 中可以一次擁有多個 onMounted 比如以邏輯的思路把每個資料區域由上至下獨立分開設置 原本的寫法是必須把資料統一寫在 data 或 methods 或 mounted Composition API 可以變成你想要哪些東西是有關聯性就寫在一起 不需要再強制性把東西都放在 data 或 methods 或 mounted 比如你要操作 text 相關的從 ref ,到 methods 的函數,到他的初始化都可以寫在最上方 接著下方就統一寫另一個假設是 num 相關的操作 在閱讀程式碼時可讀性會比較高 這也是其好處之一 所以可以多次重複調用 onMounted