VueJS 算是最近比較熱門的項目之一,官方文件也相對齊全。我們這裡要看的目前還是以 VueJS 2.x 的版本為主,提供一個簡易入門。系列文章結尾的地方,我還是會稍微提一下 VueJS 3.0 的特性,但,以目前主流來說,還是以 2 的系列為主。


安裝

使用方式目前還是以官方提供的 CLI 為主,目前的 CLI 版本在 3.x,如果你是使用舊版本的,可能會跟本系列文章有些許出入,這個部分還尚請留意一下。再者,我們必須要有 NodeJS 的環境,這裡就不贅述了。

安裝方式很簡單,就用 npm 或是 yarn 安裝到系統內就好,

npm install -g @vue/cli
# OR
yarn global add @vue/cli

接著你可以使用 vue --version 來查看一下版本,

現在的 CLI 工具有一個潮流,就是完全不需要寫設定檔。個人是覺得有利有弊,不過對於初學者來說,可以不用傷腦筋設定檔這件事情,應該是比較無痛入門的方式。

不過,倘若你需要做一些額外的設定,你還是必須搞清楚設定檔案該怎麼寫。但,這裡就不花太多篇幅講設定檔案這件事情了,有機會的話系列文末會再提及設定檔這件事情。


建立一個 Vue 專案

建立專案的方式,也是使用 CLI 的指令來建立。而在 Vue CLI 3.0 之後,也提供了圖形介面的使用方法,你若是有興趣,可以 參考官方介紹。我們這邊還是以命令列的方式來操作。建立的方式很多種,但目前我們先以建立一個完全空白的專案作為出發。建立空白專案有兩種方式,

  1. 建立在當前的資料夾當中。
  2. 建立在一個全新的資料夾。

我們這邊就將他建立在我們當前資料夾 ithome2019ironman 底下,

vue create .
# OR
vue create ithome2019ironman

確認建立在當前資料夾後,他會問你要用哪些 Features,我們使用預設的就好了。如果後續還想新增其他的工具,可以再使用 npm 或是 yarn 安裝即可。

按下 Enter 之後就會開始專案建立,就稍微等他一下就好。

如果你選擇手動安裝功能的話,會有一些項目讓你選擇,

安裝結束後,他會提示你使用 yarn serve 就可以開始開發。倘若你沒有安裝 yarn 的話,應該是 npm server 的提示命令。


開始使用開發模式

只要執行 yarn serve 就可以開始處女秀了。

稍微等他一下,直到出現完成的畫面,就可以用瀏覽器來打開,看到預設專案的畫面了。

開發環境準備好之後,我們可以先來看看這個專案的結構,

我們開發只需要關注 src 的資料夾即可,其他的部分目前可以先放著沒關係。

ps. 那個 tags 是我的 VIM 產生的檔案,你們應該不會有。

整個專案的入口處是 main.js,我們可以先來看看他做了什麼事情,

// 載入相關的套件、專案檔案等等。
import Vue from 'vue'
import App from './App.vue'

// 關閉正式環境下的提示功能,這裡可以先打開沒關係。
Vue.config.productionTip = false

// 初始化應用程序,使用 render 函式將 App 元件渲染出來
// 然後將應用程序綁定在 DOM 上面,該 DOM 的 ID 是 #app 
new Vue({
  render: h => h(App)
}).$mount('#app')

.vue 檔案

JS/HTML/CSS 這三個東西在這麼久遠的 Web 開發上,一直都是在分分合合的狀態下打滾。歷史的事情就不多提了,Vue 提供了一個解決方案,就是將三者放在 .vue 檔案中,再經由預處理器,將三者再次拆開成獨立的打包檔案。

至於欲處理器的事情,由於跟專案的設定檔案有關,系列文章文末有時間的話會再次提及。

我們先來看看這個 .vue 檔案的結構,以上述的 App.vue 為例,

由於 App.vue 是整個應用程式的入口,所以整個應用程式開始的地方就在這裡。主要區分為三個區塊,

  1. <template> 處理 HTML 樣板語言。
  2. <script> 處理 JavaScript 程式區塊。
  3. <style> 處理 CSS 程式 樣式區塊。

對於剛入門的人來說,這樣切分開來其實是相當友善的。每個區塊負責自己該做的事情。當然,你要讓他做一些不該做的事情也可以,只是目前不在討論範圍內。

由於沒有使用其他的工具,所以目前這三個區塊僅能夠處理的,就是原生的寫法。如果你要額外使用其他工具,諸如 pug, scss/sass 甚至 CoffeeScript,也是可以的。只是需要告訴他你用了什麼,以及安裝必要的套件。


<template> 樣板區塊

這個區塊是讓你寫 HTML 用的(廢話)。所以你的應用程式的大框架會在這裡。裡面除了一般的 HTML 之外,基本上可以使用 Vue 的相關屬性來操作、修改或是裝飾 DOM 元件。

官方文件 https://vuejs.org/v2/guide/syntax.html

基本的使用方法有,

  • v-bind:class 或是 :attribute="" 例如 :class="" 用以動態指定類別屬性。
  • @event 用以綁定一個事件,例如 @click 形同綁定一個 Click 事件。
  • {{ variable }} 直接顯示某一個變數資料,數字或是文字。
  • <my-component> 使用自定義的元件,例如 <HelloWorld>

屬於邏輯控制與數值的方法有,

  • v-if, v-elsev-else-if 用於 DOM 生成與否的邏輯控制。
  • v-show 用於 DOM 顯示與否的狀態判斷,後面接收邏輯值或其他數值(推薦使用邏輯值)。
  • v-for 產生一個迴圈,當你需要重複產生某一段 DOM 時適用(建議搭配 :key 使用)。
  • v-model 特別用於表單元件,用以替代輸入的接收值。

以上是比較基本面向的東西,具體的細節可以參考官方文件。我們後續文章會反覆的提到這些東西,所以在這裡先有個概念即可。

<style> 樣式區塊

樣式的部分說起來比較枯燥一點,他就是專門放 CSS 的地方而已。不過,這個 <style> 有一個屬性叫做 scoped,當你加上這個屬性的時候,在渲染出來的頁面上,就會將這個元件內的樣式 隔離 開來。

換句話說,假設該元件的樣式區塊這樣設定 <style scoped>,那麼,這邊的所有樣式,就僅只會發生在這個元件裡面,或是其子元件。有趣的地方在於,倘若子元件自身也有 scoped,則父元件並不會將子元件的樣式覆蓋,必須使用 /deep/ 或是 >>> 的寫法才行。

以上述基本的應用程式為例子,倘若 App.vue<style> 加上了 scoped,且我們加入一個叫做 p 的樣式,

/* 前略 */
p {
  color: red;
}

我們可能會期待 <HelloWorld> 裡面的 p 會變成紅色的字。但是,很不巧的 <HelloWorld> 這個子元件,本身的 <style> 也加上了 scoped。那麼,父元件的樣式並沒有辦法被套用在子元件上。

這種時候,如果真的需要將父元件的樣式,能夠套用到子元件上,你就需要使用 /deep/ 或是 >>> 來處理。

這種跳脫 scoped 的套用作法,或許跟本意有點相互違背,不過,當你使用第三方元件,想要稍微調整或是修改樣式的時候,這樣的作法其實也是不錯的。


<script> 程式區塊

這裡是這個應用程式(或是元件)的程式碼主要處理的部分。與一般你在撰寫 JavaScript 的狀況沒有太大的區別,唯一的差異是,每個元件必須要依循 export default { ... } 這樣的格式,才能被其他人看見。

原因是 import 這個方法,有興趣的人可以參考這裡:

https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Statements/import

這個區塊等於是整個 Vue 的靈魂,然後每次提到這個部分,就必須要把整個 Vue 生命週期的圖片再貼出來一次。

https://vuejs.org/v2/guide/instance.html

vue_lifecycle

圖片取自 Vue 官網

由上面的生命週期來解釋,在單一元件當中,最基本的使用方式就是這樣,

<script>
export default {
  data () {
    return {
      msg: "Hello World"
    }
  }
}
</script>

這是一個最簡易的寫法,將一個叫做 msg 的變數初始化,並且給一個字串 "Hello World" 然後他就可以用了。當然,這樣的元件的功能,就僅只是可以顯示一個叫做 msg 變數內容的元件。

目前整個元件的可使用方法與其屬性,條列如下:

  • name
  • components
  • props
  • data
  • methods
  • computed
  • watch
  • beforeCreated
  • created
  • beforeMount
  • mounted
  • beforeUpdate
  • updated
  • beforeDestroy
  • destroyed

上述可能會有疏漏,這些大概是基本上比較常用的。看起來好像很複雜,不過不要擔心,我都不會解釋,這樣就不會很複雜了。

我這個系列的文章,主要會圍繞在 components 這件事情上面,所以關於生命週期的事情,還是不要太擔心。後面的文章會慢慢的提到。

如果對於生命週期與路由有興趣的,可以參考一下我兩篇文章:

關於 vue-router 外面的兩三事
重新檢視 lifecycle 與 vue-router


關於 this 這件事

我們繼續來看 <script> 這裡面發生的事情,由於我們的元件實體,是被包含在 export default { ... } 裡面的,所以,這裡面會有一個作用域範圍 scope,這個作用域的範圍在這個實體中,會有 this 可以使用。

但是,

媽媽有說 JavaScript 的 this 天殺的難用!
具體可以參考 Kuro 的 系列文章

那麼,說到這個 this 到底在整個元件實體中扮演了什麼角色?舉例來說,

<script>
/* 前略 ... */
  data () {
    return {
      msg: 'Hello World'
    }
  }
}
</script>

如果我需要修改這個 msg 的時候,我該怎麼做?

<script>
/* 前略 ... */
  mounted () {
    setTimeout(() => {
      this.msg = 'Hello Kitty'
    }, 2000)
  },
  data () {
    return {
      msg: 'Hello World'
    }
  }
}
</script>

請留意當中的胖箭頭函式(Arrow Functions),如果不理解的可以參考一下 MDN 的說明,或是問一下 Kuro(欸)。

簡單來說,在整個元件實體中,只要使用箭頭函式的方法,基本上都是代表實體本身。不過,這種事情當然也是有例外的:

  1. beforeCreate, createdthis 實體不一定是你想的那個 this
  2. 如果有搭配 Vue-Router,有部分的方法的 this 也不是你想的那個 this

所以說,如果你在 created 使用 this 的話,這個 this 不一定是你所宣告的 Vue Instance,這一點在使用上必須要特別留意。

小結

以上大概就是入門的一些小重點。後續我們會直接著墨在元件應用上。如果有任何關於使用 Vue 的問題,歡迎到 Kuro 的粉絲團(?)詢問。

重新認識 JavaScript

這個是變成 Kuro 形狀(?)的粉絲團
Vue.js Taiwan 台灣

ITHome 鐵人賽同步刊登 VueJS 快速入門 Day 1