大家好!承前兩天,我們使用 Vite 建置了 Vue 專案,並且理解了它的資料夾結構,今天一起來更深入看一下這個專案是怎麼「組」起來的。
App.vue 中可以看到 SFC 的結構,由 <script setup></script>、<template></template>、<style></style> 組成。
繼續看看這些區塊都做了什麼事!
引入了 src/component 中的 HelloWorld、TheWelcome 這兩個組件。

HelloWorld 被使用在 <div class="wrapper"> 中的區塊。
我們到 HelloWorld.vue 裡看它做了什麼事:
<script setup></script> 中使用了以下語法:
<script setup>
defineProps({
  msg: {
    type: String,
    required: true
  }
})
</script>
defineProps(Props 意為 property)中定義了:
msg: {}:指定 msg 為組件的屬性。type: String:定義 msg 屬性的類型為 String。required: true:msg 屬性是必須提供的。而 defineProps() 的作用是:告訴子組件要「接收哪些數據」,並且這些數據必須來自「父組件」。
所以,父組件 import 這個子組件時,必須提供一個「字符串型的 msg property」(不會報錯但會警告否則會報錯)。
因此!App.vue 根組件 import HelloWorld 的時候,要提供 defineProps 裡定義的東西。
而 <template></template> 定義了基本的組件 html 結構。
<template>
  <div class="greetings">
    <h1 class="green">{{ msg }}</h1>
    <h3>
      You’ve successfully created a project with
      <a href="https://vitejs.dev/" target="_blank" rel="noopener">Vite</a> +
      <a href="https://vuejs.org/" target="_blank" rel="noopener">Vue 3</a>.
    </h3>
  </div>
</template>
它做了什麼事?
<h1 class="green">{{ msg }}</h1>:這裡的 {{ msg }} 是 Vue 中的「文本插值」,代表當父組件傳遞一個 msg 的屬性時,它會在 <h1> 標籤中顯示內容 {{ msg }}。
msg」???回頭看一下 App.vue 做了什麼:
在 <HelloWorld /> 定義了「屬性:msg」和「值:You did it」。
也就是剛剛提到的!子組件 HelloWorld 定義了 defineProps(),所以這些數據會由父組件傳到 HelloWorld 中 {{ msg }} 處。
這是因為 Vue 中有「自定義標籤」的特性,當我們將組件 import 到某個檔案,相等於我們將該組件定義為一個變數,並且我們可以在該檔案中用該變數做事。
所以 import HelloWorld from './components/HelloWorld.vue' 讓我們可以在這邊用 HelloWorld 作為自定義標籤,並渲染 HelloWorld.vue 組件的內容。
TheWelcome 在 App.vue 中也是用了自定義標籤,目前看起來就是將 TheWelcome 這個組件的東東塞進來。
看一下 TheWelcome 裡面是什麼!
看起來也是許多的組件被 import 進來⋯⋯
我們可以從開發者工具端詳一下東西是怎麼塞?進去的(我看過我覺得挺有感覺 XDDD,有種拼積木的感覺)
這邊我們來看看 HelloWorld 這個組件。
在 App.vue 中使用 <HelloWorld /> 時,會把 HelloWorld.vue 組件的內容插入到 App.vue 的結構,而這些內容會渲染為 App.vue 的一部分,有點像「填充」的過程~

因此,HelloWorld.vue 的 <div class="greetings"></div> 最終會填充到 App.vue 中 <div class="wrapper"> 內的 <HelloWorld /> 標籤所代表的地方。
不過據說 SFC 會經過 JS 編譯成為渲染函式,進而操作虛擬 DOM(這部分還沒有研究,先帶到這邊 QQ)
我自己覺得今天有比較理解 Vue 中組件相互的應用與關係,繼續繼續⋯⋯明天來看看 Vue 的模板語法(自我懷疑小裁判到目前都蠻沈默,繼續保持)
鐵人賽竟然已經完成 1/5 了!