iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 15
1
自我挑戰組

前端新手筆記-Vue.js系列 第 15

Day 15 Vue Component(元件) 介紹、建立方式、特性

本文同步發表於Andy's Blog

前言

今天終於要進入Vue Component單元勒(撒花)/images/emoticon/emoticon01.gif,而在接下來幾天我們會來慢慢介紹元件的相關內容,那我們就開始吧!

Component(元件)

何謂Component?

引用Kuro老師和Summer部落格內容整理如下:

每個 Vue.js 的應用程式都是從Vue建構式 (vue constructor) 建立根實體 (root vue instance) 開始(圖片灰底部分),再一個個將元件 (Components) 搭建上去而來的。而元件提供HTML DOM元素的擴充性這讓我們可以將程式碼封裝起來並且方便重複使用。如下圖


圖片來源:六角學院


補充:上面提到的HTML DOM元素的擴充性是什麼意思呢?
簡單來說,就是我們可以將很多組HTML,包裝在一個元件內

new Vue({
      el: '#app',
      components: {
        // register註冊
        'my-component': {
          template: `
          <div>  //最上層只能有一個tag,否則會出現下面圖示錯誤
            <div>A custom component of Vue!</div>
            <hr>
            <div>A custom component of Vue!</div>
          </div>`
        }
      }
    });
  • template中最上層只能有一個tag,否則會出現下面錯誤訊息
    https://ithelp.ithome.com.tw/upload/images/20200713/20114645Hjai597gkT.png

區域註冊

寫法如下: 練習連結
HTML部分

<div id="app">
    <first-component></first-component>
</div>

JavaScript部分

 // create a root instance
    new Vue({
      el: '#app',
      components: {      //component`s`,有s喔
        // register
        'first-component': {
          template: `
          <div>  //最上層只能有一個tag,Vue單節點特性
            <div>A custom component of Vue!</div>
            <hr>
            <div>A custom component of Vue!</div>
          </div>`
        }
      }
    });
  • 區域註冊範例補充
    JavaScript部分
<script type="text/x-template" id="forCardTemplate">
    <div class="card" style="width: 18rem;">
      <div class="card-body">
        <h5 class="card-title">卡片資料:{{ data }}</h5>
      </div>
    </div>
  </script>

  <script type="module">
    var card = {
      data: function(){
        return {
          data: '這裡有一段話'
        }
      },
      template: '#forCardTemplate',
    };

    var app = new Vue({
      components:{
        //自定義名稱 //使用的組件內容
        'card':card
      },
      el: '#app',
      data: {
      }
    });

  </script>

圖解:
透過變數 card 來定義組件內容,然後在components選項中定義你想要使用的組件!
https://ithelp.ithome.com.tw/upload/images/20200713/20114645FpC68r1hhO.png

全域註冊

  • 寫法介紹:撰寫時有兩個參數,分別為「組件名稱」及「選項物件」,在下方範例中「組件名稱」為 first-component ,「選項物件」則為其後的內容。
  • 缺點:不管有沒有使用到這個元件,其元件就一定會載入,拖慢網頁載入時間。
  • 寫法如下: 練習連結
    HTML部分
<div id="app">
    <first-component></first-component>
</div>

JavaScript部分

 Vue.component('first-component',{
    template: `
     <div>  
     <div>A custom component of Vue!</div>
     <hr>
     <div>A custom component of Vue!</div>
     </div>`
 })
 // create a root instance
    new Vue({
      el: '#app',
    });

模板應用

  1. template literal(樣板字面)
  2. x-template
  3. vue file

1.template literal

透過 `` 符號將HTML內容包起來

Vue.component('first-component',{
    template: `
     <div>  
     <div>A custom component of Vue!</div>
     <hr>
     <div>A custom component of Vue!</div>
     </div>`
 })

2.X-template

當今天我們template內容較為冗長時,我們可以透過script標籤加上type="text/x-template"指定一個id來使用。將封裝內容獨立出來。
寫法如下:

  <script type="text/x-template" id="my-component">
    <div class="component">
    A custom component of Vue!
    </div>
  </script>

  <script>
    // global register
    Vue.component('my-component', {
      template: '#my-component',
    });
    // create a root instance
    new Vue({
      el: '#app',
    });
  </script>

小結論

區域註冊全域註冊最大差別就是

  • 區域註冊,僅能在綁定的實體內使用。如上方例子:綁定"#app"。這時,如果同一個頁面有另外一個實體"#app2",這邊的元件就不能被掛載到實體"#app2"中。
  • 全域註冊,則可以提供多組實體使用
  • 由於 HTML 不分⼤⼩寫的特性,使用⾃定義的標籤時限定全⼩寫 (可加入破折號 - ) 的標籤名稱方便辨識

Component特性

一、元件資料都是獨立的
1.透過props向內部組件傳遞數據
2.透過emit event觸發事件將資料往外送

圖片來源:六角學院

二、data必須是一個函數
寫法如下:

Vue.component("button-counter", {
  data: function() {
    return {
      count: 0
    };
  }
});

備註:為何元件內資料必須為函數呢?
主要原因就是在ES6以前,function是切分變數最小單位,而在Vue元件中,為了避免元件與元件資料污染,因此Vue強制規定子元件data屬性必須是函式,確保每個元件資料都是獨立的。

複習一下

下面寫法是全域註冊還是區域註冊?

var CustomBlock = Vue.component('custom-block', {
      template: `<div class="block">B</div>`,
    });>

答案是全域註冊喔,別搞錯摟~

參考資料


上一篇
Day14 練習做一個貨幣轉換器
下一篇
Day16 Vue Component(元件) props、emit介紹
系列文
前端新手筆記-Vue.js30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

我要留言

立即登入留言