Vue-單一元件檔(Single-file components)

優缺點

在許多 Vue 專案中,可以先定義一個「全域組件」Vue.component,接著再創建一個「Vue 實體」new Vue({el:'#app'}),並且將全域組件指定到頁面中的一個容器元素中。

這種方式卻僅適合中小型的專案,但是當專案更於複雜,會出現一些缺點:

  • 全域定義問題(Global definitions):每個組件(component)的命名不能重複。
  • 字串模板問題(String templates):在元件中的template屬性只能用字串,當使用編譯器(例:vscode)撰寫內容時,無法有效地以文字顏色區分、辨別內容
  • CSS 不支援問題(No CSS support):在元件中只能提供 HTML 及 JavaScript,無法支援 CSS
  • 預處理問題(No build step):元件預設中只能使用 HTML 及 ES5,不能使用預處理工具,例:Babel

單一元件檔(Single-file component)」就可以解決上述問題,它同時包含 HTML、JavaScript 及 CSS,一個.vue檔案就代表一個組件,且支援使用 Webpack 或 Browserify 等打包建置工具。

檔案樣板結構

.vue檔案的基本內容結構:

1
2
3
4
5
6
7
8
9
10
11
12
13
<template>
<div>
<!--HTML內容 -->
</div>
</template>

<script>
// JAvaScript內容
</script>

<style>
/*CSS內容 */
</style>

若不喜歡 HTML、JavaScript 與 CSS 三者合一,也可以改為將 JavaScript 及 CSS 分離成獨立的檔案再載入的寫法:

1
2
3
4
5
6
<!-- my-component.vue -->
<template>
<div>This will be pre-compiled</div>
</template>
<script src="./my-component.js"></script>
<style src="./my-component.css"></style>

templete 區塊

<template>樣板裡的內容會被編譯為元件中 templete屬性的值,樣板中只能有一個根元素,也就是說所有內容要包在一個<div></div>中。

預設使用 HTML,但可以使用 lang 屬性指定為其他樣板系統,例:

1
<template lang='jade'>...</template>

script 區塊

這個區塊中只能有一個,且最終必須匯出一個 Vue 物件。

預設為 JavaScript,要使用其他 JS 套件可以使用 require()。如果有安裝 babel-loader 在支援 ES2015 的環境中,則可以使用 import 及 export 語法。例:

1
2
3
4
5
import Vue from 'vue';
import loadingFunc from '../Loading';
export default {
<!--component content -->
};

這裡記得 from 的部份,如果使用的是 node_modules 也就是由 npm / yarn 安裝的套件,直接寫套件的名稱;而如果是自己的 JavaScript 檔,則要在檔名前加上 ./。

style 區塊

一個.vue檔案可以有零到多個<style>,且可以是全域或區域的<style>區塊。

<style>的預設為全域的,如果想要限制為區域作用(只在該組件中有效),可以加上scoped屬性:

1
<style scoped>...</style>

預設為 CSS,也可以更換為 SCSS:

1
<style lang="sass">...</style>

簡易範例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<template>
<div>
<p>{{ greeting }} World!</p>
</div>
</template>

<script>
module.exports = {
data: function () {
return {
greeting: 'Hello'
}
}
}
</script>

<style scoped>
p {
font-size: 2em;
text-align: center;
}
</style>

撰寫.vue 檔案

先確定專案的結構,根目錄會有一個index.html作為執行 Vue 的入口;接著在 src 資料架,主要的程式碼都會放在這裡;main.js是程式的進入點,也可以透過 webpack.config.js 設定檔修改、自定義配置;myApp.vue則是這裡的重點,最終會匯出一個 vue 組件。

1
2
3
4
5
6
7
8
project根目錄
|_index.html
|_src
|_main.js
|_component
|_myApp.vue
|_build
|_webpack.config.js

index.html

放置在根目錄底下的index.html

1
2
3
4
5
6
7
8
9
10
11
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>hello</title>
</head>
<body>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
  • 第 8 行,這是 Vue 的進入點。
  • 這個檔案中只有最基本的 HTML 內容,沒有 CSS、JavaScript,第 9 行,建置後的檔案會自動引入。

myApp.vue

component 資料夾下方放置所有的 vue 組件,示範一個myApp.vue組件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<template>
<div>
<h1>Hello</h1>
<p class="hello">{{ msg }}</p>
</div>
</template>

<script>
export default {
data () {
return {
msg: '這是一個 Vue 組件檔!'
}
}
}
</script>

<style scoped>
h1 {
color: green;
}

.hello {
font-size: 1.5em;
color: blue;
}
</style>

main.js

myApp.vue組件建立好之後,接著就可以引入到main.js
main.js。是程式的進入點,也可以透過 webpack.config.js 設定檔修改、自定義配置。

基礎的內容:

1
2
3
4
5
6
import Vue from 'vue';

new Vue({
el: '#app',
template: '<h1>Hello Vue</h1>',
});

如果要引入myApp.vue組件,則要添加一些內容,如下:

1
2
3
4
5
6
7
8
9
10
import Vue from 'vue';
import MyApp from './myApp';
import MyApp2 from './myApp2';

/* eslint-disable no-new */
new Vue({
el: '#app',
components: { myApp, myApp2 },
template: '<div><myApp></myApp><myApp2></myApp2></div>',
});
  • 第 1 行import'vue'是使用 node_modules 由 npm / yarn 安裝的套件,所以可以直接寫套件的名稱。
  • 第 2 行import'./MyApp'是自己的 JavaScript 檔,則要在檔名前加上 ./
  • 第 8 行,為 vue 實例添加components屬性,其值為引入組件,如有多個組件則用逗號分隔。
  • 第 9 行,這樣就可以將 templete 樣板中改寫為<myApp></myApp>,立即使用引入的組件,但切記只能有一個<div>根元素,所以所有內容都要包在其中。

組件加在組件中

除了上述將所有組件都引入到 main.js 中的做法,也可以把 myApp2 組件加在 myApp1 組件中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<template>
<div>
<h1>Hello</h1>
<p class="hello">{{ msg }}</p>
<myApp2></myApp2>
</div>
</template>

<script>
import myApp2 from './myApp2'

export default {
data () {
return {
msg: '這是一個 Vue 組件檔(myApp1)!'
}
},
components: { myApp2 }
}
</script>
  • 在第 10 行中,將 myApp 組件檔import進來
  • 接著在第 18 行,將 myApp 組件 assign 到 component 屬性中
  • 最後,在第 5 行,就可以在<template>中使用了

組件命名及使用

不論 vue 組件的命名方式為何,在 html 中使用時,一律為 kebab-case (不分大小寫,一律轉為「小寫並加上 dash 線」)

假設 vue 組件為MyApp,在 HTML 呼叫使用時,需轉換為<my-app></my-app>

1
2
3
4
5
// 三種命名方式

my-first-component //kebab-case
myFirstComponent //camelCase
MyFirstComponent //PascalCase

參考資料

© 2020 Leah's Blog All Rights Reserved. 本站访客数人次 本站总访问量
Theme by hiero