在 Vue 幫我們解決的事情這篇文章中,已經用一個簡單的方式介紹元件的概念。
當時只是提到模板結構跟資料抽離,並且讓結構重複使用,帶上不同的資料。
有沒有覺得這東西跟什麼很像?
對... 就是上一篇文章的 v-for
在做的事情。
實際上這只是一個最淺的概念來讓新手去「感受」什麼叫做元件,但 v-for
在做的事情,純粹只是讓畫面重複被渲染,嚴格說起來不能稱之為元件。
Vue 的元件,除了能讓模板「重複使用」之外,更重要的還是能在整個 Vue 應用程式中的任何位置使用。
而且除了「畫面」之外,還會可以包含一些資料加工與邏輯整合。
我們剛學習網頁的開發方式,就是你我都熟知的三個檔案:index.html
、app.js
、style.css
的做法,已經做到基本的關注點分離,不過只要單一頁面的資料量過於龐大,上面說的這三個檔案就是無止盡的變大,看到幾百行原始碼算是家常便飯,更誇張的還可能會到幾千行。
雖然這樣做不是不可行,不過時間不用太久,寫完程式一個月後,遇到需求修改,要從「程式山」中找到要改的地方絕對不會是一件容易的事情。
於是我們可以把網頁畫面當成拼圖一樣切割,Header
當作一塊,主要內容當成另一塊,Footer
再切一塊,拆成不同的區塊看待。
甚至還可以依據各區塊內容的獨特性,再讓拼圖的大小更小一些。
最後把這些內容整理成一個一個的元件檔案,我們稱作 單一元件檔 SCF (sigle component file)。
Vue 是一個漸進式框架,前幾篇用到的程式寫法也都可以用來定義元件,預計下一篇文章會寫到。
不過元件最方便,還是直接使用 Vue 的腳手架(vite)時,可以直接使用 .vue
副檔名的檔案,每一個這種檔案,我們就可以稱他叫做單一元件檔案。
以初始化 vite 時會看到的內容來說,會看到這樣的長相:
<scrip setup>
import HelloWorld from './components/HelloWorld.vue'
</script>
<template>
<div>
<a href="https://vitejs.dev" target="_blank">
<img src="/vite.svg" class="logo" alt="Vite logo" />
</a>
<a href="https://vuejs.org/" target="_blank">
<img src="./assets/vue.svg" class="logo vue" alt="Vue logo" />
</a>
</div>
<HelloWorld msg="Vite + Vue" />
</template>
<style scoped>
.logo {
height: 6em;
padding: 1.5em;
will-change: filter;
transition: filter 300ms;
}
.logo:hover {
filter: drop-shadow(0 0 2em #646cffaa);
}
.logo.vue:hover {
filter: drop-shadow(0 0 2em #42b883aa);
}
</style>
一個單一元件檔案分成三個標籤組成
script setup
標籤:他就是我們寫 setup()
的地方,標籤中的 setup
是 Vue 提供的語法糖,尤雨溪大大曾說這很黑魔法,他可以讓我們直接省略 setup()
函數,而且變數不用再 return
出來,模板即可使用。
也就是如果只有寫 <script></script>
,就還是必須寫這樣的內容:
<script>
import { ref } from 'vue'
export default {
setup() {
const count = ref(0)
return {
count
}
}
}
</script>
有了 script setup
語法之後,就可以省略成這樣:
<script setup>
import {ref} from 'vue';
const count = ref(0);
</script>
此外,上面 vite
的例子中, style
的內容長這樣:
<scrip setup>
import HelloWorld from './components/HelloWorld.vue'
</script>
有看到那個 import 嗎,沒錯! Vue 的 SCF 檔案適用於 ES Module 語法。
我們可以在 script 中引用其他元件來使用,也可以用語法引用其他套件來用。
template
標籤<template>
<HelloWorld msg="Vite + Vue" />
</template>
他就是我們寫 HTML 的地方,跟之前的文章範例中,寫在 #app
裡面的那些東西一樣。
當然,如果使用 v-if
或是 v-for
時有需要,這個標籤也還是可以再寫一個 template
標籤,完全是沒有問題的。
style scoped
標籤<style scoped>
.logo {
height: 6em;
padding: 1.5em;
will-change: filter;
transition: filter 300ms;
}
.logo:hover {
filter: drop-shadow(0 0 2em #646cffaa);
}
.logo.vue:hover {
filter: drop-shadow(0 0 2em #42b883aa);
}
</style>
就是寫 CSS 的地方。
我們在寫原生的 CSS ,即使拆分成多個檔案,只要掛到同一份 HTML中,那所有檔案都會影響到這份 HTML,沒辦法只限定特定區域。
不過 SCF 的 Style 標籤,可以多寫一個 scoped 屬性,表示要讓內容只限定在這個檔案內,其他地方不適用。
反之,如果沒有寫 scoped 屬性的話,寫的資料又會變成全域的了。
這篇文章中記錄單一元件檔 SCF 的組成,直接把元件拆成一個又一個的檔案,視覺上會變得很直觀,需要維護時也能變得比較好找資料。
不過單一元件檔 (.vue) 一般只會在 vite
的環境中使用,如果專案不是使用 vite
開發,而是使用 CDN 引入 HTML 的話,定義一個元件會是不同的寫法。
下一篇預計來介紹,如何在「輕前端」中使用元件。