Vue.js: 元件 Components 簡介 - 註冊與使用

什麼是元件?

每個 Vue.js 的應用程式都是從Vue建構式 (vue constructor) 建立根實體 (root vue instance) 開始,再一個個元件 (Components) 搭建上去而來的,透過元件的方式能讓開發者將程式碼封裝而更好重用。

大概就像是葡萄串的概念吧!

葡萄

如何使用元件?

可使用全域或局部的方式註冊元件。

全域註冊 (Registration)

使用Vue.component(tagName, options)來註冊一個元件。注意,元件的註冊必須在 Vue Instance 初始化前完成

如下例,這是一個顯示訊息、點擊按鈕後會說 Hi 的元件。

Demo。

Vue.js: 元件 Components

程式碼。

<div id="app">
  <prompt-component></prompt-component>
</div>
Vue.component('prompt-component', {
  template: '<div><p>${ message }</p><button @click="sayHi">Say Hi!</button></div>',
  delimiters: ['${', '}'],
  data: function () {
    return {
      message: 'Hello World!'
    }
  },
  methods: {
    sayHi: function() {
      alert('Hi');
    }
  }
})

var vm = new Vue({
  el: '#app'
});

// 由於部落格會把使用雙花括號的內容吃掉,所以設定 delimiters 以顯示完整程式碼。

局部註冊 (Local Registration)

如果不需共用,可使用局部註冊。

改寫上例。

var Prompt = {
  template: '<div><p>${ message }</p><button @click="sayHi">Say Hi!</button></div>',
  delimiters: ['${', '}'],
  data: function () {
    return {
      message: 'Hello World!'
    }
  },
  methods: {
    sayHi: function() {
      alert('Hi');
    }
  }
};

var vm = new Vue({
  el: '#app',
  components: {
    'prompt-component': Prompt
  }
});

DOM 模版的解析 (DOM Template Parsing Caveats)

模版的來源有兩種:DOM 模版 (DOM Template) 和 字串模版 (String Template)。在 DOM 模版狀況下,若瀏覽器無法正確渲染 DOM Elements,則 Vue.js 就無法對模版做正確的解析。如下,錯誤的標籤包法導致渲染錯誤。

Vue.js: 元件 Components

解法有兩種

  1. 改用字串模版 (String Template)
  2. 使用is屬性

is

component 的:is屬性可動態決定要渲染的模版。is屬性可解決在特定 HTML 標籤包含格式下的問題,像是<table>只能包<tr>而非客製化標籤<my-row>

正確的使用標籤。

Vue.js: 元件 Components

<div id="app">
  <table>
    <tr is="example-item"></tr>
  </table>
</div>
<script type="text/x-template" id="my_component_with_template">
  <tr>
    <td>A</td>
    <td>B</td>
    <td>C</td>
  </tr>
</script>
var vm = new Vue({
  el: '#app',
  delimiters: ['${', '}'],
  components: {
    'example-item': {
      template: '#my_component_with_template'
    }
  }
});

字串模版 (String Template)

如果是字串模版 (string template) 就沒有這個問題。

data 必須是函數

在 Vue Instance 中,data 可以是 object 或 function,但元件的 data 只能是 function,這是因為元件內會各自擁有自己的 data,而非共用的關係。請見 Vue.js: data、v-model 與雙向綁定-資料型別

組成元件

為了共用程式碼,我們會將可重用的部份拆解為「元件」,而父子元件有可能必須溝通。父子元件溝通時,父層使用 props down 將資訊傳遞給子層,而子層透過 events up 的方式 (即$emit) 將結果傳回父層。

props down / events up

圖片來源:Composing Components

這裡有一個範例,Todo List 的每個項目是使用元件「todo-item」。todo-item的資料由父層代入,若要刪除項目會從 remove method 發出this.$emit('remove')來觸發父層的del method。詳細說明可參考-Todo List: Vue.js Example

以上參考 Components — Vue.js


comments powered by Disqus