iT邦幫忙

2022 iThome 鐵人賽

DAY 12
0
Modern Web

不用去柬埔寨也能活摘 Vue系列 第 12

[Vue] Day12 起手式:Composition API

  • 分享至 

  • xImage
  •  

Composition API 是 Vue3 推出後最大的特點,是 Vue 元件的另一種編寫方式。

那我們今天要與各位介紹的是,當 Vue2 的專案準備升級成 Vue3 時,應該如何改寫。又或者是在我們準備以 Vue3 撰寫專案時,應該如何起手呢?那就馬上來看看吧!

首先,讓我們先來看看 Vue2 的 Options API 結構:

export default {
  props: {},
  
  data() {
    return {};
  },
  watch: {},
  computed: {},
  methods: {},
};

由上方的程式碼可以看到,Options API 讓我們在撰寫上多了一層制約,導致邏輯散落在各選項中,程式碼也因此變得難以理解,在閱讀上也因為難以分割造成困難。

Composition API 優點

  • 程式能依照功能分類使用,增加可讀性
  • 新增封裝功能,能夠跨元件使用,增加重複使用性
  • 提供更好的 TypeScript 支持

setup 函式

與 Options API 不同的是,Vue3 的 setup 函式可以在裡面去定義我們所需要的東西,例如:datamethodscomputedlifecycle 等。且會在元件尚未被建立之前執行,而使用的是 Composition API 的實際位置。setup 函式也可以回傳一個物件,物件中內容都將給予元件的其他部分:計算、方法、生命週期及元件的模板等等。

<script>
export default {
  data() {
    return {
    };
  },
};
</script>

data (響應式資料)

在 Vue3 中,可以透過 reactive 的方式去建立響應式物件,或透過 ref 建立響應式變數。

reactive

reactive() 首先會接受一個普通物件,並將此作為參數,接著再回傳一個響應式的物件狀態,而此種響應式轉換則稱作為「深度轉換」。要注意的是 reactive 只接受 Object 及 Array 做監聽,而當我們在取資料時,並不會使用 .value

<template>
  <div id="ithome_example">
    <p>{{ name }}</p>
  </div>
</template>

<script>
import { reactive } from "vue";

export default {
  setup() {
    const data = reactive({
      name: "2022_ithome",
    });
  },
};
</script>

由此可見,data 在回傳物件時,是透過內部的 reactive 讓他成為響應是物件的。

ref

ref() 是一個可以接受任何型別的參數,並回傳一個響應式且可變動的 ref 物件,而在物件中只會包含一個名為 value 的屬性,但要注意的是,ref 並不會對 Object 與 Array 的內部屬性做監聽。

補充一點,如傳入的型別是物件的話,內部會呼叫 reactive() 並將其轉換為響應式物件。

<template>
  <div id="ithome_example">
    <p>{{ name }}</p>
  </div>
</template>

<script>
import { ref } from "vue";

export default {
  setup() {
    const name = ref("2022_ithome");
    return { name };
  },
};
</script>

假如我們 console.log (name) 的話,可以發現 Composition API 的 ref 是一個 Object,但若我們想改變 name 的值,就需要去更改他的 value。而 ref 除了可以當值來用,也可以把它當作一個 Vue 的節點。

msg.value = '2022_ithome_example'

以上,我們可以看到在定義資料的時候,會用 ref 或 reactive,那就有人疑問了:該如何選用呢? 其實在大多數的情況下兩者都是可以的,看個人習慣及團隊的協調。

Ref 自動解構

當我們把將 ref 分配給響應式物件的 property 時,則 ref 物件就會自動解構。

import { ref, reactive } from 'vue';

const count = ref(1);

const data = reactive({});
data.count = count;

const obj = ref({});
obj.value.count = count;

但只有物件會去解構 ref ,陣列不會。所以陣列在給值時,一樣需要加上 .vaule

import { ref, reactive } from 'vue';

const arr = ref([]);
arr.value[0] = count;
arr.value[1] = count.value;

Setup 參數

當我們在執行 setup 函式的時,元件的實體還尚未建立,而在 setup 函式裡的 this 並不是實體的引用。所以當我們想訪問 propsattrsslotsemit 時,則可以透過 setup 函式提供的兩個參數來訪問:

  • props
  • context

props

props 是響應式物件,可用來在 setup 函式中去取得父元件所傳遞的 prop。

<script>
    export default {
      props: ['name'],
      setup(props) {
        console.log(props.name);
      },
    };
</script>

要注意的是,如想使用 ES6 的解構 const { msg } = props,則會失去響應性。因此 Vue3 提供了我們 toRefs 的方法,讓我們能夠將響應式的物件轉換成普通的物件,並且將每個 property 轉成指向原始物件 property 的 ref 物件。

import { toRef } from 'vue';
export default {
  props: ['msg', 'name'],
  setup(props) {
    const { name, msg } = toRefs(props);
  },
};

舉個例子,這是我們在 Component 的 HTML:

<HelloWorld name="Hello World"/>

那在 HelloWorld.vue 的組件中的 Props 的值,就可以如下寫法去接應:

export default {
  props: ['name'],
  setup(props) {
    const data = props.name;
    console.log(data);
  }
}

這樣子我們的 console.log 就會輸出 Hello World 囉!這樣是不是清楚了許多

那當然的,我們也能將 Props 轉換為 Ref:

import { toRef } from 'vue'
export default {
  props: ['name'],
  setup(props) {
    const name = toRef(props, 'title');
    console.log(name.value); 
  }
}

而從這邊可以看到以上程式碼我們使用的是 toRef,既然使用了自然也要跟各位稍微介紹一下呢!

toRef

toRef() 與 ref() 都可用來建立響應式資料的,但 ref 會複製一份新的資料,而 toRef() 則只會保持對其源頭的 property 進行響應式連接,即使 property 不存在,toRef() 也會回傳一個可用的 Ref 物件。

toRefs

toRefs 雖然與 toRef 只差了一個字母,但兩個功能是不同的喔!toRefs 可以將響應式物件轉成普通物件,並且將每個 property 轉換成指向原始物件所對應 property 的 Ref 物件。比如說,我們如果使用 ES6 去解構 const { msg } = props的話,就會失去響應性。這時候就可以讓 toRefs 幫我們解決了。

watch

watch 顧名思義,監聽的意思。可用來監聽某個數據,並觸發相對應的處理。而在 watch 的物件下,我們可以使用 keyvalue 的方式去定義我們想觀察的值以及其相對應的操作。而當我們資料發生變化時,便可以呼叫函式,而這時候的函式就會新增兩個傳入的參數:改變前的值改變後的值,我們就可以利用此函式去做跟此資料變動相關的處理。

<script>
export default {
  watch: {
    test: {
      name: function () {
        console.log("2022_ithome");
      },
    },
  },
};
</script>

而 watch 在 Vue 中有兩種使用方式:

  • $watch:Vue 實體的函數,可使用此函數去註冊監聽器
  • watch:Vue 實體的屬性,屬性設置的物件在實體建立時會呼叫 $watch 註冊監聽器

$watch 是註冊監聽器的函數,而 watch 則是提供給開發者在實體上更方便的去設置監聽器,而其實 watch 本身也是使用 $watch 註冊監聽器的。


上一篇
[Vue] Day11 實體物件與主要 API
下一篇
[Vue] Day13 methods及computed 的資料整合與邏輯運算
系列文
不用去柬埔寨也能活摘 Vue30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言