不論是在 Vue 實體中建立區域元件,或是使用
Vue.component
來建立全域元件,這些都只適合在用在簡單的小元件上,當元件變得複雜時,在開發上會變得很沒效率,這時可以使用 Vue 提供的單一元件檔來解決這個問題。
為什麼要使用單一元件檔
我們來看看在使用 Vue 實體或Vue.component
建立元件時會有什麼缺點。
1. 全域定義的問題
使用Vue.component
定義的元件是全域的,意謂著元件的名稱不能重複。
2. 字串模板的問題
在元件中的template
屬性只能使用字串,因此當你在編寫樣板內容時,編輯器就無法以顏色顯示;而且只能以 \
倒斜線的方式分行,寫起來不方便、效率太差。
3. CSS 的問題
在元件中只能提供 HTML 及 JavaScript ,漏掉了 CSS 的支援。4. 前置處理的問題
元件預設只能使用 HTML 及 ES5 JavaScript,不能使用前置處理工具,所以像是 Jade 及 Babel 等就無法使用。單一元件檔可以解決以上的問題,它同時包含了 HTML、JavaScript 及 CSS,而且因為一個檔案就代表一個元件,在管理上也更有效率。同時也支援 Webpack 或 Browserify 等打包工具。
如何使用單一元件檔
單一元件檔的副檔名為.vue
,範例如下:
Vue<template>
<div class="hello">Hello {{ name }}</div>
</template>
<script>
module.exports = {
data: function () {
return {
name: 'Tony'
}
}
}
</script>
<style>
.hello {
font-size: 3em;
text-align: center;
color: green;
}
</style>
不過這個檔案不能直接使用,必須透過 vue-loader
來解析文件,組成一個 CommonJS 模組,最後透過 module.exports
輸出一個 Vue.js 元件。
<template> 區塊
樣板預設使用 HTML,但是可以使用lang
屬性來指定使用其他的樣板系統,例如:
<template lang="jade">
樣板裡的內容會被編譯成元件的 template
屬性的值。樣板內只能有一個根元素。這個區塊只能有一個。
<script> 區塊
預設使用 JavaScript。如果有安裝 babel-loader 或 buble-loader 則可以使用 ES2015 語法。要使用其他 JavaScript 套件可以使用 require(),在支援 ES2015 的情況下,也可以用 import 及 export 語法。這個區塊只能有一個,而且最終必須匯出 Vue.js 物件。
<style> 區塊
預設使用 CSS,也可以換成 SASS,例如:<style lang="sass">...</style>
<style>
的內容預設是全域的,如果你想讓它只在這個元件中有效(區域),可以加上 scoped 屬性,例如:
<style scoped>...</style>
一個 .vue 文件中可以同時使用全域和區域的 <style>
區塊。這個區塊可以有零個或多個。
自定義區塊
使用 vue-loader 10.2.0+ 以上版本,你也可以加入自己定義的區塊。註解
最頂層的註解使用 HTML 註解語法:<!-- 這是註解 -->
區塊中則使用該區塊原本的註解語法。
編輯器外掛
Sublime Text 可以搜尋 vue syntax highlight 外掛,安裝後可以對 .vue 文件做語法色彩顯示。使用 Vue-cli 工具
Webpack 是一個打包工具,可以將你以模組方式寫的程式碼等等檔案整合成單一個檔案。它非常靈活好用,但是也因為這樣,前置的設定就有點麻煩。Vue.js 官方提供了一個命令列工具 vue-cli ,其中就提供 Webpack 的配置設定,我們可以直接使用它來建置網站。
安裝及執行
首先使用 npm 或 yarn 來安裝,記得安裝成全域的方便使用:npm install --global vue-cli
或
yarn global add vue-cli
註:如果使用 yarn ,記得把 yarn global bin
指令顯示的路徑加入 $PATH
,不然會出現找不到指令的錯誤。測試看看指令能不能用,在 shell 中執行:
vue --version
如果輸出版本號就表示指令可以使用。接著就可以來建立專案了。先切換到你想建立專案的目錄,然後執行:
vue init webpack hello
init
會建立新專案;webpack
是選擇要建立的專案樣板;hello
是專案目錄的名稱。你可以在 vuejs-templates 查看專案樣板:
- webpack-simple:只包含 vue-loader 的簡單樣板。
- webpack:在 webpack-simple 上再包含熱重載、測試、linting、CSS抽取等工具,是最完整的樣板。
- browserify-simple:只包含 vueify 的簡單樣板。
- browserify:在 browserify-simple 上再包含熱重載、測試、linting、CSS抽取等工具,是最完整的樣板。
- simple:只包含一個 html 檔。
安裝指令會透過問問題的方式讓你選擇是否安裝它提供的套件,你可以一路按 Enter 使用預設值。完成後,它會提示你如何開始:
- 進入專案目錄:
cd hello
- 安裝套件:
npm install
或yarn
- 執行:
npm run dev
或yarn run dev
Ctrl + C
可以停止伺服器。你可以查看 README.md,裡面有提到建置相關的指令,例如:
npm install
:安裝相依套件。npm run dev
:運行開發用伺服器,並且在檔案變動時自動重新整理。npm run build
:建立最終可執行的檔案,輸出到dist
目錄。npm run unit
:執行單元測試。
撰寫第一個 .vue 文件
index.html
首先來看看專案根目錄下的 index.html:HTML<!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>
註解告訴我們,建置的檔案會自動加入,所以這個檔案只提供了最基本的 HTML 內容,沒有 CSS、也沒有 JavaScript 等等內容,唯一要注意的就是 <div id="app"></div>
這是要讓 Vue 執行的進入點。接著來看
src
目錄,你的主要程式都會放在這。
src/main.js
這個檔案是程式的進入點,是由build/webpack.base.conf.js
設定檔中的 entry
所指定,如果有需要可以更改它。為了瞭解整個開發流程,我們先忽略 vue-cli 建立的內容,你可以將 main.js 中的內容全部刪掉或註解,然後輸入以下內容:
JavaScriptimport Vue from 'vue'
/* eslint-disable no-new */
new Vue({
el: '#app',
template: '<h1>Hello Vue</h1>'
})
然後執行 yarn run dev
,順利的話,你可以在瀏覽器看到結果。但你很可能會遇到一些錯誤,例如:
Errors:
2 http://eslint.org/docs/rules/indent
2 http://eslint.org/docs/rules/no-tabs
1 http://eslint.org/docs/rules/eol-last
1 http://eslint.org/docs/rules/no-new
ESLint 是一個 JavaScript 語法檢查器,我們在建立專案時,選擇的是 JavaScript Standard Style ,所以 ESLint 用這個標準來幫我們檢查語法風格,這些錯誤訊息只是說風格不符,並不是真的程式有錯。要如何修改:
- indent:縮排的方式。標準必須用 2 個空白,如果你用 tab 就會出現這個錯誤。
- no-tabs:是否允許 tab 。標準不能使用 tab ,如果你用了就出現錯誤。
- eol-last:檔案結尾是否要保留一個空行。標準要求要,檔案最後沒保留空白行就會出現錯誤。
- no-new:是否允許使用 new。標準不允許,用了就會出現錯誤。但是因為我們必須使用,所以加一行註解來取消 ESLint 的檢查。
.eslintrc.js
,你可看到它的規則是繼承(extends)自 standard
,後面的 rules
項目可以讓你設定規則,這裡設定的規則會覆蓋繼承的規則。我們可以加入 2 行來強制使用 tab:
'rules': {
'indent': ['error', 'tab'],
'no-tabs': 0,
...略
想要查詢更多的規則,可以看 ESLint Rules。回到
main.js
上,你應該會發現,程式碼和一開始學 Vue.js 時差不多,只是拆成 index.html
和 main.js
兩個檔案。
src/MyApp.vue
來建立我們的第一個 .vue 檔,MyApp.vue 內容如下:Vue<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>
<template>
區塊只能(必須)有一個根元素,其他元素只能放在其中。<script>
必須要匯出 Vue.js 物件。我們的 .vue 檔完成了,怎麼用呢?回到
main.js
加入內容後如下:
JavaScriptimport Vue from 'vue'
import MyApp from './MyApp'
/* eslint-disable no-new */
new Vue({
el: '#app',
template: '<MyApp></MyApp>',
components: { MyApp }
})
這裡記得 from
的部份,如果使用的是 node_modules
也就是由 npm / yarn 安裝的套件,直接寫套件的名稱;而如果是自己的 JavaScript 檔,則要在檔名前加上 ./
。接著我們指定
components
為 MyApp.vue 所匯出的元件。如果有多個元件,可以逗號分隔。然後就能把樣板內容換成
<MyApp></MyApp>
,也可以寫成 <MyApp/>
,立即使用我們所建立的元件。以下示範如何把其他 .vue 檔加在一起,這裡借用原本的
App.vue
:方式一:加在
main.js
中
JavaScriptimport Vue from 'vue'
import MyApp from './MyApp'
import App from './App'
/* eslint-disable no-new */
new Vue({
el: '#app',
template: '<div><MyApp/><App/></div>',
components: { MyApp, App }
})
記住,template
只能有一個根元素,所以我們要用 <div>
來包含它們。這樣你應該知道如何加入其他元件了。現在,將 main.js
還原,以接續下一個方式。方式二:加在 MyApp.vue 中:
HTML<template>
<div>
<h1>Hello</h1>
<p class="hello">{{ msg }}</p>
<App/><!-- 元件放在這 -->
</div>
</template>
<script>
import App from './App'
export default {
data () {
return {
msg: '這是第一個 Vue 元件檔!'
}
},
components: { App }
}
</script>
...略
在 <script>
中一樣 import
元件檔進來,接著指定給 components
,然後就能在 <template>
中使用它了。現在你已經知道怎麼寫 .vue 檔、怎麼使用 .vue 檔及怎麼混合使用多個 .vue 檔了。你可以試試看把
components/Hello.vue
加進來:
HTML<template>
<div>
<h1>Hello</h1>
<p class="hello">{{ msg }}</p>
<App/>
<Hello/>
</div>
</template>
<script>
import App from './App'
import Hello from './components/Hello'
export default {
data () {
return {
msg: '這是第一個 Vue 元件檔!'
}
},
components: { App, Hello }
}
</script>
...略
Build
最後,當你完成了所有的工作,就可以執行npm run build
或
yarn run build
所有的內容就會組合打包起來輸出到 dist
目錄中。在
dist
中的內容必須放在伺服器中才能執行,所以在開發中可以使用
npm run dev
或
yarn run dev
在開發伺服器中瀏覽。
元件的命名及使用
不管你的元件如何命名,在使用的時候都要注意大小寫可能造成的名稱問題。在 HTML 中,任何元素都是不分大小寫的,所以元件名稱在轉成 HTML 元素時會轉成小寫並加上分隔線,以下舉例:- 檔案名稱 App.vue:轉換成
<app></app>
,即使用你寫成<App></App>
是可以,但瀏覽器看到的是仍是小寫的元素。 - 檔案名稱 MyApp.vue:轉換成
<my-app></my-app>
,這就是要注意的情況,如果元素名稱用錯,Vue.js 會出現未註冊元件的警告。
本文網址:http://blog.tonycube.com/2017/05/vuejs-10-single-file-components.html
由 Tony Blog 撰寫,請勿全文複製,轉載時請註明出處及連結,謝謝 😀
由 Tony Blog 撰寫,請勿全文複製,轉載時請註明出處及連結,謝謝 😀
我要留言
留言小提醒:
1.回覆時間通常在晚上,如果太忙可能要等幾天。
2.請先瀏覽一下其他人的留言,也許有人問過同樣的問題。
3.程式碼請先將它編碼後再貼上。(線上編碼:http://bit.ly/1DL6yog)
4.文字請加上標點符號及斷行,難以閱讀者恕難回覆。
5.感謝您的留言,您的問題也可能幫助到其他有相同問題的人。