iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 16
0
自我挑戰組

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

vue3 Composition API 學習手冊-16 組件設計入門

  • 分享至 

  • xImage
  •  

如同「vue.js 學習手冊 框架的選擇與導入」這篇文章中提到的,我們使用框架能更方便地進行前後端分離式的開發;享受Virturl DOM提升頁面效能外;另外還有一個很大的特色是「模組化的開發架構」,把常用到的元素設計成一個組件在頁面中引用上去,也可以隨時將它拆除,不會影響到頁面其他的部分,這樣的模組化設計是在各個領域都能加速設計的一種方式。

組件設計的精神在於高聚合、低耦合,簡單說就是一個組件要能夠容易的被引入到各個頁面,自己本身也能獨立運作,不要有依存性,接下來我們就一步一步來看看如何使用vue來完成組件的設計。

這篇文章我們先來看看在單一文件中該如何去設計一個組件。

組件定義


首先我們先來看,如何將一個<button>設計成vue組件:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://unpkg.com/vue@next"></script>
    <style>
        button {
            padding: 5px;
        }
    </style>
</head>
<body>
    <div id="app">
        <vuebutton></vuebutton>
    </div>
</body>
</html>
<script>
    const myVue = Vue.createApp({})
    myVue.component("vuebutton",{
        template: `<button>我是按鈕</button>`
    })
    myVue.mount("#app");
</script>

這樣執行結果如下:

可以看到我們在vue裡面透過components來宣告了一個組件,名稱訂為vuebutton,然後在template定義了組件的HTML,接下來在<body>中,使用我們定義的名稱<vuebutton></vuebutton>就可以呼叫這個組件出來,另外在CSS的部分可以看到使用button。

需要特別注意的是組件的名稱都必須使用小寫英文,如果我們這樣定義組件名稱:VUEBUTTON, vueButton…瀏覽器都會報出這樣這樣的錯誤。

參數傳遞


接下來我們會想到,不可能在每個組件中HTML的部分都完全相同,例如這個按鈕也許在不同的地方,需要顯示不同的名稱,例如:確定、取消…等等,這時候我們可以透過在使用組件的時候,透過props將值傳遞組件,組件能夠接收props來進行變化(同樣props要使用全部小寫的英文字)。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://unpkg.com/vue@next"></script>
    <style>
        button {
            padding: 10px;
        }
    </style>
</head>
<body>
    <div id="app">
        <vuebutton title="確定"></vuebutton>
        <vuebutton title="取消"></vuebutton>
    </div>
</body>
</html>
<script>
    const myVue = Vue.createApp({})
    myVue.component("vuebutton",{
        props: ["title"],
        template: `<button>{{ title }}</button>`
    })
    myVue.mount("#app");
</script>

props就是在使用Components時可以透過父層傳遞給子層用的一個參數,碰到設計的比較複雜的組件,還會再包著另外一個組件,也是透過這個方式來傳遞。

我們也可以傳遞一個以上的props給組件,有以下的幾個方式:

方法一. 陣列

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://unpkg.com/vue@next"></script>
    <style>
        button {
            padding: 10px;
        }

        h2 {
            font-size: 18px;
            font-family: "微軟正黑體";
        }
    </style>
</head>

<body>
    <div id="app">
        <vuebutton title="iPhone" start="10"></vuebutton>
        <vuebutton title="iPad" start="100"></vuebutton>
    </div>
</body>

</html>
<script>
    const myVue = Vue.createApp({})
    myVue.component("vuebutton",{
        props: ['title', 'start'],
        template: `<button>{{ title }} 庫存 {{ start }} 件</button>`,
    })
    myVue.mount("#app");
</script>

方法二 物件

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://unpkg.com/vue@next"></script>
    <style>
        button {
            padding: 10px;
        }

        h2 {
            font-size: 18px;
            font-family: "微軟正黑體";
        }
    </style>
</head>

<body>
    <div id="app">
        <vuebutton title="iPhone" start="10"></vuebutton>
        <vuebutton title="iPad" start="100"></vuebutton>
    </div>
</body>

</html>
<script>
    const myVue = Vue.createApp({})
    myVue.component("vuebutton",{
        props: {
            title: {
                type: String,
                required: true
            },
            start: {
                type: String,
                default: "0",
            },
        },
        template: `<button>{{ title }} 庫存 {{ start }} 件</button>`,
    })
    myVue.mount("#app");
</script>

可以看到使用方法2去傳遞Props可以有比較多的參數設定,例如是否是必須接收的(required)、預設值(default)以及資料型態(type),也因為方法2有填寫Default,所以可以看到在使用組件的時候,若沒有填寫對應的Props,其結果也會和方法1相同。

資料型態的部分有以下幾種:

  • String
  • Number
  • Boolean
  • Array
  • Object
  • Date
  • Function
  • Symbol

所以看起來我們上面案例的”start”應該使用Number來當參數比較適合,但要注意的是若傳遞的參數不是String,在HTML上面就需要使用v-bind的方式來進行,例如:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://unpkg.com/vue@next"></script>
    <style>
        button {
            padding: 10px;
        }
        h2{
            font-size: 18px;
            font-family: "微軟正黑體";
        }
    </style>
</head>

<body>
    <div id="app">
        <vuebutton title="iPhone"></vuebutton>
        <vuebutton title="iPad" :start="100"></vuebutton>
    </div>
</body>

</html>
<script>
const myVue = Vue.createApp({})
myVue.component("vuebutton",{
    props: {
        title: {
            type: String,
            required: true
        },
        start: {
            type: Number,
            default: 0,
        },
    },
    template: `<button>{{ title }} 庫存 {{ start }} 件</button>`,
})
myVue.mount("#app");
</script>

否則會收到如下的錯誤

今天的文章就先到這邊,下一篇文章會來介紹組件的方法和資料上面的應用。


上一篇
vue3 Composition API 學習手冊-15 安裝Chrome擴充功能
下一篇
vue3 Composition API 學習手冊-17 組件的資料和函數
系列文
網頁前端框架 Vue 3 從頭開始(重新挑戰)30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言