iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 27
0
自我挑戰組

網頁前端框架 Vue 3 從頭開始(重新挑戰)系列 第 27

vue3 Composition API 學習手冊-27 以前叫mixin的東西

  • 分享至 

  • xImage
  •  

前幾篇文章已經介紹過vue的元件化設計的特色,不僅僅是頁面中的小元件,我們甚至可以將整個頁面都做成一個元件,今天來分享的是除了元件能共用之外,連函數也可以共用,舉個例來說,我們在頁面中若要使用之前設計的下拉式選單元件,而這個下拉式選單元件中的值都是取自於外部(json或API),如果要滿足這樣條件下的共用元件時,我們就需要在每個頁面中axios對應的資料,所以大概會是如下圖的狀況:

應該發現到問題了吧?每個頁面都要重新import axios也都要重寫axios城市上面的邏輯,所以我們可以把常用的函數抽取出來,讓多個元件共用函數,這種東西呢,在vue2稱為mixin,但因為mixin會有需多全局污染的問題,所以在vue3的composition API中已經更改了作法,但不免還是會碰到一些vue2學習的朋友,我們暫時還是把他稱為mixin吧?其實就是共用函數的作法。

首先我們要把原先放在App.vue裡面的axios程式和下拉選單一起搬移出來,下方是我們修改後的App.vue頁面內容

<template>
  <h1>{{ "Please select the item you like below" }}</h1>
  <div class="linkArea">
    <router-link to="/">Home</router-link>
    <router-link to="/about">About</router-link>
    <router-link
      :to="{ path: '/product', query: { id: 'a1023931', category: '1' } }"
      >Product</router-link
    >
    <router-link to="/contact">Contact</router-link>
  </div>
  <router-view></router-view>
</template>
<style lang="scss" scoped src="./assets/scss/main.scss"></style>

接下來我們在src中新增一個utils的資料夾,並且新增一隻檔案CommonMixin.js,檔案內容如下:

import axios from "axios";

export default function (){
  let responseData = null;
  const getJsonData = async function(file){
    try{
      responseData = await axios.get(file);
      let data = responseData.data;
      return { data }
    } catch (error){
      console.log(error);
    }
  }
  return { getJsonData };
}

可以看得出來寫法跟之前的有些許不同,主要是在這個檔案新增了一個名為getJsonData的方法,另外因為拆分檔案之後需要注意非同步處理,就是一定要拿到資料之後才能夠繼續往後執行,所以加上了async與await,不過除此之外跟之前的請求方式差異並不大。

接下來我們設定兩個目標,我們想讓網站中About與Contact這兩個頁面使用下拉選單這個元件,並且透過共用的函數去索取資料,首先是About.vue這個頁面(其實兩個頁面要做的動作差不多)。

About.vue

<template>
    <div>About</div>
    <DropdownMenu :items="state.selectData.system"></DropdownMenu>
</template>
<script>
import DropdownMenu from "@/DropdownMenu.vue";
import CommonMixin from "@/utils/CommonMixin.js"
import { onBeforeMount, reactive } from "vue";
export default {
  setup(){
    const { getJsonData } = CommonMixin();
    const state = reactive({
      selectData: {
        system: null
      },
      selectedData: {
        system: null,
      },
    })
    onBeforeMount( async () => {
        const { data } = await getJsonData("json/vueComponent.json");
        state.selectData = data;
    })
    return { state }
  },components:{
    DropdownMenu
  },
};
</script>
  • 6、7兩行主要就是import,分別是下拉式選單的元件與mixin檔
  • 第11行將共用函數導入到vue裡面
  • 12~19一樣是規劃vue監聽的資料部分
  • 25~27行是使用到的元件
  • 20~23則是原先準備要使用axios的部分,因為資料並需載入之後我們才能做其他的動作,所以選擇在onBeforeMount時處理,且使用ES6的async, await來等待資料的傳入,而抽取json資料的部分我們用建構式把它拿出來(data),另外我們實作的getJsonData需要帶入檔案與路徑,所以在括號裡面傳給他,待拿到資料之後就將資料寫入state.selectData。

其實看到這樣的結果之後,另外一頁也就是依樣畫葫蘆:

Contact.vue

<template>
    <div>Contact</div>
    <DropdownMenu :items="state.selectData.provider"></DropdownMenu>
</template>
<script>
import DropdownMenu from "@/DropdownMenu.vue";
import CommonMixin from "@/utils/CommonMixin.js"
import { onBeforeMount, reactive } from "vue";
export default {
  setup(){
    const { getJsonData } = CommonMixin();
    const state = reactive({
      selectData: {
        provider: null
      },
      selectedData: {
        provider: null,
      },
    })
    onBeforeMount( async () => {
        const { data } = await getJsonData("json/vueComponent.json");
        state.selectData = data;
    })
    return { state }
  },components:{
    DropdownMenu
  },
};
</script>

看到這邊是不是覺得vue很神奇的都可以把許多共用的部分抽出來,方便使用也方便維護,這也就是我們之前提到透過框架開發的好處,今天的文章就先到這邊。

以下是這個範例的連結


上一篇
vue3 Composition API 學習手冊-26 Dynamic Route
下一篇
vue3 Composition API 學習手冊-28 打包與回顧
系列文
網頁前端框架 Vue 3 從頭開始(重新挑戰)30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言