到目前為止真的只是利用 vue-cli 建立個前端開發環境,先前花了幾篇文章說明前端種種機制 webpack, eslint, npm .... 等,接著我們就來一同了解 Vue 相關所需具備的基本知識吧!
前言
本篇文章會說明一些開發上最基本所需具備的相關知識,讓大家可以快速進入 Vue 的世界,但你我都知道的魔鬼往往都是藏在細節中,因此建議最好在入門後,直接掃過官方說明文件一輪,可以對細節瞭解地更全面。
主要 Vue 實體 (Instance)
開啟專案根目錄下 index.html 後,發現什麼東西都沒有,只有存在一個 id = "app"
的 div 元素。
故事的開始就是從這個 main vue instance 而來,開啟 main.js 程式進入點可以看到被創建的主要 vue 實體。
- el 表示這個 vue instance 創建後會掛載取代
id="app"
的元素 - router 是傳入 vue-router 組件 (ES6 屬性簡寫語法糖)
- template 是表示將 el 定義的標籤取代為此 HTML 模板
- components 表示此 vue instance 所使用到的子組件,在此為 App 組件;因此在載入此 instance 後,因 template 中存在有 <App/> 標籤,因此 <App/> 又會被 App 組件中的 template HTML 模板所取代。
App.vue 檔案結構為 vue 所建議的組件撰寫方式,就是在一份檔案中撰寫組件所需的 HTML、Javascript 及 CSS 代碼;上文有提到 main vue instance 子組件有包含 App 組件,因此 main vue instance 中 template 包含的 <App/> 標籤就會被 App.vue 中定義的 Template HTML 模板取代,因此最終呈現在畫面上就是此 HTML 元素。
最終同一個元素的呈現在畫面上轉化過程如下圖所示。
建立組件
vue 官方所建議的組件撰寫方式就是將 HTML、JavaScript 及 CSS 寫在一個副檔名為 vue 的檔案中,各自以 Template、Script 及 Style 標籤區隔,以下針對各項目進行介紹。
script
會在這邊建立 vue 實體並 export 出去外部,而在建立 vue 實體的時候可以定義資料、屬性、方法及生命週期觸發事件行為,這些都可以幫助開發人員更靈巧地操作組件。
- data : 定義組件資料 (在此建立了 birthYear 數字型態變數)
- computed : 計算屬性,可以設計 getter / setting 來操作特定資料
- watch : 監聽特定資料 / 計算屬性的變動,可獲得修改前後數值
- method : 自定義方法供此組件使用
- components : 若有包含其他子組件,可以利用此方法加入組件
- 其他還有與 instance 生命週期相關 Hook 例如 mounted、updated.. 等可使用
<script>
export default {
name: 'basicControl',
// 資料區塊
data() {
return {
birthYear: 1983
}
},
// 屬性區塊
computed: {
// read only
status: function() {
return '我出生於' + this.birthYear + '年'
},
// read and write
age: {
get: function() {
return new Date().getFullYear() - this.birthYear
},
set: function(v) {
this.birthYear = new Date().getFullYear() - v
}
}
},
// 監聽區塊
watch: {
birthYear: function(newValue, oldValue) {
toastr.warning(`birth year has changed from ${oldValue} to ${newValue}`, 'User Status')
}
},
// 方法區塊
methods: {
showStatus: function() {
toastr.success(this.status, 'User Status')
}
}
}
</script>
template
這個區塊就是放置組件需要呈現在畫面上的 HTML 元素,其中 Vue 提供了一些如同 angular 1 預設的 directive 可以操作 (ex. v-if, v-show, v-for... )。預計呈現的畫面如下。
這邊介紹一下最常使用到的 directive 如下:
v-bind:prop (簡寫為 :prop)
單向綁定子組件之特定 props 資料,在此使用 v-bind:value 表示單向綁定 input 元素 props 中的 value 資料 (可簡寫為 :value ),而傳遞進去的資料為 age。
v-model
雙向綁定子組件名為 value 的 props 資料,在此表示雙向綁定 input 元素 props 中的 value 資料 ,而傳遞進去的資料為 age。說穿了 v-model 也只是語法糖而已,他會透過 v-bind:value + v-on:input 兩種 directive 自動實作出 2 way binding 的效果;也就表示如果自己建立的組件如果想要具有 v-model 的效果,可以自行建立 props 的 value 資料,並且監聽到 value 異動就 emit input 事件並傳遞新 value 值到父組件即可,而父組件因為設置 v-model 的關係會自動在收到 input 事件後自行更新資料,達到雙向綁定效果。
v-on:event (簡寫為 @event)
監聽特定事件,在此使用 v-on:click 表示當 button 元素被觸發 click 事件後,會 emit 該事件通知父組件並執行 showStatus 方法。
<template>
<div class="basic-control">
<h2> Basic vue Control</h2>
<div class="info-box card">
<h4>{{this.status}}</h4>
<p> age : <input type="number" v-bind:value="age"> (v-bind)</p>
<!-- v-bind:value 可使用簡寫 :value 表示 -->
<p> age : <input type="number" v-model="age"> (v-model)</p>
<button type="button" v-on:click="showStatus"> Show Status Toastr</button>
<!-- v-on:click 可以使用簡寫 @click 表示 -->
</div>
</div>
</template>
style
支援 CSS / SCSS / Stylus 等 Style 語法,可以透過 lang 標籤設置;其中若希望此 style 只在組件中作用,可以加上 scoped 來進行限制。
<style scoped lang="scss">
$padding-size: 10px;
.info-box {
width: 400px;
padding: $padding-size;
margin: 0 auto;
text-align: left;
}
</style>
檢視結果
透過 v-bind 綁定的 input 在變動資料的時候是不會影響父層資料 (單向綁定)
透過 v-model 綁定的 input 在變動資料的時候是會影響父層資料 (雙向綁定),並且由於我們透過 watch 監看 birthYear 數值變動,如果有異動會透過 toastr 輸出前後修改值
最後擊 Show Status Toastr 按鍵會觸發 showStatus 方法,輸出提示訊息。
參考資訊
若有更好的建議或做法再請不吝指導一下囉! 感謝!
希望此篇文章可以幫助到需要的人
若內容有誤或有其他建議請不吝留言給筆者喔 !