iT邦幫忙

2021 iThome 鐵人賽

DAY 6
0
Modern Web

別再說我不會框架,網頁 Vue 起來!系列 第 6

元件基本使用

Vue.js 的網頁是由元件組合而成,利用 HTML 元素重複使用元件。

由元件組成網頁

圖取自What are Vue Components?

元件 ?

Components 是可以被重複使用的實體,會利用像是<button-counter> 這樣自訂的元素來使用元件。元件一樣也可傳入 data computed watch methods 這些 options。
ex:

// 建立根實體/根元件
const app = Vue.createApp({})

// 定義 button-counter 全域元件
app.component('button-counter', {
  data() {
    return {
      count: 0
    }
  },
  template: `
    <button v-on:click="count++">
      You clicked me {{ count }} times.
    </button>`
})

app.mount('#components-demo')

複用性

要使用幾個就有幾個,也因為每一個元件就代表一個全新的實體,當點擊這些按鈕時,每一個元件都會各自計算次數。

<div id="components-demo">
  <button-counter></button-counter>
  <button-counter></button-counter>
  <button-counter></button-counter>
</div>

組織元件

應用程式的架構由樹狀結構的元件組成,最常見的網頁可以被拆分成 headersidebarcontent area 這些區塊,如果要在模板中使用這些元件,就必須註冊他們,讓 Vue 知道這些元件。(元件註冊有兩種類型,globallocal)

傳遞資料至元件

在 component 中註冊 props 屬性。

ex:

const app = Vue.createApp({})

app.component('blog-post', {
  props: ['title'],
  template: `<h4>{{ title }}</h4>`
})

app.mount('#blog-post-demo')
<div id="blog-post-demo" class="demo">
  <blog-post title="My journey with Vue"></blog-post>
  <blog-post title="Blogging with Vue"></blog-post>
  <blog-post title="Why Vue is so fun"></blog-post>
</div>

當值傳至 prop 時,它就會變成元件的屬性,在模板中也就可以取用到這個值。

監聽子元件事件

父元件可以透過v-on 或是 @ 監聽子元件的所有事件,而子元件可以使用內建的 $emit 方法發送事件名稱。
ex:


const app = Vue.createApp({
  data() {
    return {
      posts: [
        { id: 1, title: 'My journey with Vue'},
        { id: 2, title: 'Blogging with Vue'},
        { id: 3, title: 'Why Vue is so fun'}
      ],
      postFontSize: 1 // 父元件增加 postFontSize 的 data 屬性
    }
  }
})

// 註冊 blog-post 元件
app.component('blog-post', {
  props: ['title'],
  template: `
    <div class="blog-post">
      <h4>{{ title }}</h4>
      // 發送一個名稱為 enlargeText 的事件出去
      <button @click="$emit('enlargeText')">
        Enlarge text
      </button>
    </div>
  `
})

app.mount('#blog-posts-events-demo')

<div id="blog-posts-events-demo" class="demo">
  <!-- postFontSize 值寫入樣式中,控制所有文章的字體大小 -->
  <div :style="{ fontSize: postFontSize + 'em' }">
    <blog-post
       v-for="post in posts"
       :key="post.id"
       :title="post.title"
       @enlarge-text="postFontSize += 0.1"
    ></blog-post>
  </div>
</div>

元件之間的資料傳遞:
Props in, Event out
Passing Data

圖取自How To Pass Data To A Child Component In Vuejs


補充

Global components

不需要使用 export/import,任何地方都可以使用註冊在全域的元件。

ex:

const app = Vue.createApp({})

// 元件註冊在 app 上 (app 為根實體或稱根元件)
app.component('component-a', {
  /* ... */
})
app.component('component-b', {
  /* ... */
})
app.component('component-c', {
  /* ... */
})
// 掛載在 #app 上
app.mount('#app')
<div id="app">
  <component-a></component-a>
  <component-b></component-b>
  <component-c></component-c>
</div>

Local components

不推薦把元件都註冊進全域中,因為未使用到的元件也會一併被打包,增加不必要的下載量。

ex:

// 元件先以物件方式定義
const ComponentA = {
  /* ... */
}
const ComponentB = {
  /* ... */
}
const ComponentC = {
  /* ... */
}
// 使用 components option 註冊
const app = Vue.createApp({
  components: {
    'component-a': ComponentA,
    'component-b': ComponentB
  }
})

下篇預告

  • 元件續

每日一句:
即使長這麼大,終究無法適應收假的心情 /images/emoticon/emoticon02.gif


上一篇
模板中的 Directive 指令 (下)
下一篇
[Part 1 ] Vue.js 的精隨-元件
系列文
別再說我不會框架,網頁 Vue 起來!30

尚未有邦友留言

立即登入留言