iT邦幫忙

2022 iThome 鐵人賽

DAY 6
2
Modern Web

真的好想離開 Vue 3 新手村 feat. CompositionAPI系列 第 6

真的好想離開 Vue 3 新手村 - Day 6: 什麼是 Vue SFC 檔?如何被編譯?feat. Vite

  • 分享至 

  • xImage
  •  

Outline

  1. 什麼是 SFC 檔
  2. 認識 SFC 檔的組成 - Language Block
  3. SFC 檔會如何被解析(其實不算重要,但因為我很好奇

什麼是 SFC 檔

在閱讀 Vue 官方文件的時候,會一直看到 SFC,那什麼是 SFC

SFCSingle-File Component 的縮寫,也就是 Vue 專案中常見的 .vue 檔,是 Vue 的一大特色。

Vue SFC 檔案內可以封裝單一元件的:

  • 邏輯 (JavaScript /<script>)
  • 模板 (html /<template>)
  • 樣式 (CSS / <style>)

直接來看看常見的 .vue 程式碼架構:

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

export default {
  setup() {
    const greeting = ref("第六天而已,還好嗎?");

    return {
      greeting,
    };
  },
};
</script>

<template>
  <p class="greeting">{{ greeting }}</p>
</template>

<style>
.greeting {
  color: red;
  font-weight: bold;
}
</style>

Language Block

前面提到 .vue 內一般會包含三個區塊(模板/邏輯/樣式),先來看一下詳細的規定:

  • <template>

    • 每個 .vue 最多只能有一個 <template>
    • 內容會被傳到 @vue/compiler-dom 預編譯成 JavaScript 的渲染函式
  • <script>

    • 每個 .vue 最多只能有一個 <script> (不包含 <script setup> )
    • default export 形式需為 Vue component options object、一般物件或是defineComponent 的回傳值。
  • <script setup>

    • 每個 .vue 最多只能有一個 <script setup> (不包含 <script> )
    • 會經過預處理,作為元件的 setup() 函式使用
    • 裡頭的 Top-level bindings 都會自動暴露給 template,故在 template 可以直接取用。(註:top-level binding 指的是這個 scope 內宣告在最外層的變數。)
  • <style>

    • 每個 .vue 可以有多個 <style>
    • scopemodule 屬性可以選用,也可在 SFC 內混合使用

Tag Attribute 屬性

介紹在語言塊 tag 中常用到的屬性:

  • lang
    這些 Language Block 都可以用 lang 屬性來表明使用的語言:
<script lang="ts"></script>
<template lang="pug"></template>
<style lang="scss"></style>
  • scoped in <style>
    <style> 標籤中可以使用 scoped,表示樣式只要套用在當前元件,不會影響到其他元件,能避免 style 互相影響。
<style lang="scss" scoped></style>
  • setup in <script>
    是 Vue 3 Composition API 的語法糖,簡化原先 <script> + setup() 的寫法。
<script setup></script>

自訂 block

除了以上三種類型的區塊(block),SFC 檔內還可以使用自訂的 blocks,但就要在建構工具中特別設定,告訴 vite「專案有自定義 block」,告訴他如何處理,舉例一個實際插件如 @intlify/vite-plugin-vue-i18n,就有自訂 <i18n> block,讓開發者可以在裡面定義多國語系,使用文件


SFC / .vue 檔會如何被解析

murmur: 其實這件事對新手來說並不是很重要啦,但因為我很好奇。

瀏覽器並不認識 .vue,在開發期間,我們不能像以前一樣直接透過 live server 在瀏覽器上預覽專案,這也是為什麼我們需要用到 Vite 或 Vue Cli 等建構工具,建構工具會根據 Vue 提供的 loader - @vue/compiler-sfc 來編譯 .vue 檔。

/images/emoticon/emoticon19.gif所以 .vue 檔是怎麼被解析編譯的?
可能跟你想的不太一樣。
(至少跟我一開始想的不太一樣啦,我一開始以為他會把每個 .vue 檔的 <template> 剪下來接在一起哈哈哈哈哈(用笑聲掩飾尷尬))

每個 SFC 都會被編譯成一個 JavaScript 的 ES module -- 一個渲染函式

骨架

SFC 中 <script><template> 的內容會被編譯成渲染函式,每次要用到該元件或頁面時,就會呼叫這個渲染函式。(這也是為什麼我們可以在元件中 import 其他 .vue 檔,因為每個 .vue 檔最終都是一個 JavaScript 模組)

樣式

SFC 中 <style>的部份:

  • 在開發環境(development):會用 <style> tag 的方式掛載,以支援熱更新(hot update)。
  • 在正式環境(production):也就是正式打包後,所有樣式檔會打包到同一個 .css 檔案中,請參考 Day 4: 從 npm run build (vite build) 簡單認識打包

來去瀏覽器驗證看看

✓ 建構工具為 vite
✓ 啟動本地伺服器 (npm run dev)
✓ 使用預設設定,沒有特別做調整

讓我們打開瀏覽器來看看~

  1. 開發者工具 > Network Tab
  2. 重整網頁,讓網頁重新載入
  3. 底下會有每次 HTTP request 載入的檔案
    • 記得勾 JS 或是 All

是不是看到很多熟悉的名字?

:欸,他後面明明就是 .vue?說好的不認識?

「雖然他還有 .vue,但你再仔細看看他,他已經是 .js 了。」

點擊檔案後,可以從右邊欄位看到 .vue 檔被編譯過的結果,像是最熟悉的陌生人,可以依稀看到當初的模樣。

在開發環境(development),會用 <style> tag 的方式掛載 .vue 中的樣式,這件事會由一個 Javascript module 來處理,以支援熱更新(hot update)。

將開發者工具切回 Elements,<head> 內確實被插入多個 <style> tag,可以點開看看內容,基本上每個 SFC 檔都有對應的 <style> tag。

::::::warning::::::
注意是用 Vite 啟動本地開發環境(npm run dev) ,才會看到類似上面的結果。

  1. 用 Vue Cli 就不是這樣喔!他們編譯 .vue 的方式是一樣的,但 Vue Cli 在開發期間就已經把所有檔案 bundle 在一起,所以沒辦法從瀏覽器看到單獨 vue 檔編譯後的樣子。
  2. 至於 npm run build (vite build) 和 preview 的結果,可以到 Day 4: 從 npm run build (vite build) 簡單認識打包 看看。

明天會進一步說明 Vue 3 的語法糖 <script setup>

參考資料


上一篇
真的好想離開 Vue 3 新手村 - Day 5: Option API 和 Composition API 比一比
下一篇
真的好想離開 Vue 3 新手村 - Day 7: 深入了解 <script setup> 語法糖
系列文
真的好想離開 Vue 3 新手村 feat. CompositionAPI31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
Amigo
iT邦新手 5 級 ‧ 2023-02-18 11:40:25

好棒!解答了JS運作的疑問

我要留言

立即登入留言