iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 15
1
自我挑戰組

前端史萊姆與Vue的三十天時光冒險系列 第 15

Day15 萬丈高樓平地起(3):元件 Components 簡介

本文同步發表於斜槓女紙部落格:Day15 萬丈高樓平地起(3):元件 Components 簡介

Day15 萬丈高樓平地起(3):元件 Components 簡介

嗨!今天持續跟大家聊聊Vue.js的基礎觀念。
曾經有位大大要我們思考:「為什麼要用Vue?」「為什麼不用其他的框架?」

對我來說,第一點就是入門容易。以我自己為例,只有懂粗淺皮毛的JavaScript,甚至在公司工作時基本上也只有碰HTML和CSS,但因為Vue實際操作起來簡單上手,不用花太多時間google十萬個為什麼,光這點就省下我不少的時間。

另一個原因則是Vue的元件化開發一直讓我躍躍欲試,如果跟我一樣在公司只能使用HTML和CSS調整每一項專案的話,相信你一定都會遇到這個問題:『好不容易克服重重障礙,千辛萬苦地依據設計師極富創意的UI畫面,把實際網頁切版出來後,客人、甚至更多時候是你家PM,改動一點小地方以後,整個網頁就無法見人了...』

這種HTML和CSS耦合(改了一點毛髮而牽動了全身,或者是想要改點東西,需要在一堆代碼裡面找半天)情況一直讓我深感頭疼,但因為Vue可以將html元素組件化,每個單一元件不一定會很大一包,甚至可以是一個按鈕、一個輸入input,在任何不同的項目、複雜的情境中都可以隨時重複取用,並且維護簡單,大大降低了代碼耦合的情況。

今天就是要來跟大家聊聊元件(Components)


什麼是 Vue component (元件)?

承如上面所說,如果將所有的程式碼都撰寫在同一個檔案中,會顯得相當複雜而且凌亂,在維護上相當困難。

而 Component 有個相當棒的特性,就是將 HTML 封裝起來,掛載在網頁上的時候,只需要透過自定義的 tag 如 <components></components> 就可以掛載至網頁上。而如果有重複的區塊也可以使用同一個元件,下圖就是利用元件的方式建立一個頁面

Vue component 示意圖

圖片取自於Possible to use VueJS SFC components with with template in rendered html?

要特別注意的是,元件的 data 只能是函式(Function)。原因是 Vue component 元件 是可以 重複利用 的,而且在正常的情況下,它會使用不同的資料,因此,data是函式(Function)的話,每次註冊組件,則會回傳一個新的物件。

特性:

  • 可單一出現,也可以元件包元件
  • 可以獨立運作,也可重複使用
  • 資料都是獨立的狀態

全域元件(Global Component)

利用Vue.component(tagName, options)來全域註冊元件,必須在new Vue初始化之前建立完成。

  • tagName:元件的tag名稱,可以在HTML中被拿來當標籤使用,所以須保有唯一性,不能與其他全域元件的名稱重複。
  • options:選擇性參數,可將前面所學到的options屬性(data、methods、filters、computed、watch)放進去使用,注意data只能是function型態(必須使用return回傳),如果沒有使用function,Vue將會停止執行。
Vue.component('tagName', {
    // options
})

實際範例,說明如下:

在HTML中命名<card-components></card-components>的元件標籤

<div id="app">
  <card-components></card-components>
</div>

在JS中利用Vue.component引入元件內容,並宣告#app為Vue應用程式的作用範圍

Vue.component("card-components", {
  template: 
  `<div class="card">
  <div class="card-body">
    <p class="card-text">{{text}}</p>
  </div>
</div>`,
  data(){
    return{
      text:'我是全域註冊元件'
    }
  }
});


new Vue({
  el: '#app',
});

使用檢查工具的話應該可以看到下列畫面

全域註冊-檢查工具畫面

不過使用全域註冊的缺點是,不管有沒有使用到這個元件,其元件就一定會載入,因此,使用全域註冊會將原本不需要的組件載入進來,整體而言,會拖慢網頁載入的時間。


區域元件(Local Component)

若該元件不需要共用,可以採用局部註冊的區域元件。也可以減少上面提到的全域註冊的缺點。

我們改寫上一個案例來看看,實際範例

首先,HTML元件標籤維持原本的樣子:

<div id="app">
  <card-components></card-components>
</div>

將JS改寫如下:

let vm = new Vue({
  el: "#app",
  components:{
    'card-components' :{
       template: `<div class="card">
                      <div class="card-body">
                        <p class="card-text">{{text}}</p>
                      </div>
                  </div>`,
       data(){
         return {
          text:'我是局部註冊元件'
         }
       }
     }
  }
});

使用檢查工具的話應該可以看到下列畫面

局部註冊-檢查工具畫面


使用 x-template 建立元件

隨著專案規模的擴增,整個專的HTML模板區塊可能越來越多、越來越大包。如果只是用 template直接掛上 HTML元素時,程式碼的維護和管理相對也會變得比較困難。

這時候,我們可以把整個 HTML模板區塊透過<script id="xxx" type="text/x-template"> </script>這樣的方式來封裝我們的HTML模板,這種方式通常被稱為「X-Templates」。

來看看實際範例吧!

HTML程式碼如下:

<div id="app">
  <card-components :food="item" v-for="(item, key) in list" :key="key"></card-components>
</div>

<script type="text/x-template" id="cardElement">
  <div class="card my-5">
    <div class="card-body">
      <p class="card-text">{{food.name}}</p>
    </div>
  </div>
</script>

JS改寫如下:

Vue.component('card-components', {
  props:['food'],
  template: '#cardElement',
});




var app = new Vue({
  el: '#app',
  data: {
    list: [ 
			{ 
        id: 'a',
        name: '晚餐吃鐵板燒' 
      },
      { 
        id: 'b',
        name: '午餐吃陽春麵' 
      },
      { 
        id: 'c',
        name: '早餐吃火腿蛋吐司'
      }
		]
  }
});

檢查工具畫面如下圖:
x-template-檢查工具畫面

使用x-template時要特別注意,這個方法比較適用於HTML模板區塊特別大的專案或極小型的應用,但是其它情況下請避免使用,因為這會將模板和該組件的其它定義分離開。

今天就先分享到這兒,明天來和大家聊聊關於props的基本觀念唷~


參考資料


上一篇
Day14 萬丈高樓平地起(2):Vue 的生命週期中的同步非同步
下一篇
Day16 萬丈高樓平地起(4):元件間的溝通橋樑Props(1)
系列文
前端史萊姆與Vue的三十天時光冒險30

尚未有邦友留言

立即登入留言