文章

組件基礎

在 Vue 3 中,組件是構建應用的核心概念之一。組件可以看作是可重用的、獨立的、具有自身邏輯和樣式的小模塊,用來構建應用的界面。透過組件,我們能夠更好地拆分大型應用,將各部分的邏輯與視圖分離,從而提高開發效率和可維護性。

1. 組件的基本概念

Vue 中的組件實際上是擁有自己模板(template)、數據(data)和邏輯(methods)的 Vue 實例,可以像 HTML 標籤一樣使用。每個組件都有其自己的作用域,可以接受外部數據(props),也可以發送事件(events)來與其他組件進行交互。

2. 組件的創建

1. 全局註冊組件

全局註冊的組件可以在應用中的任何地方使用。在 Vue 3 中,使用 app.component 來全局註冊組件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<div id="app">
  <!-- 使用自定義組件 -->
  <my-component></my-component>
</div>

<script>
const app = Vue.createApp({});

app.component('my-component', {
  template: '<p>Hello from the component!</p>'
});

app.mount('#app');
</script>

在這裡,我們創建了一個名為 my-component 的全局組件,並且在模板中像標籤一樣使用它。

2. 局部註冊組件

局部註冊的組件只能在某個 Vue 實例或其他組件內使用。這樣可以有效避免全局組件造成的命名衝突,讓組件僅在需要的地方可用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<div id="app">
  <!-- 使用自定義組件 -->
  <my-component></my-component>
</div>

<script>
const MyComponent = {
  template: '<p>Hello from the local component!</p>'
};

const app = Vue.createApp({
  components: {
    'my-component': MyComponent
  }
});

app.mount('#app');
</script>

在這個例子中,我們將 MyComponent 作為局部組件註冊到 Vue 實例中,因此它只能在這個實例中使用。


3. 組件的數據傳遞

1. 父組件向子組件傳遞數據(props)

父組件可以透過 props 將數據傳遞給子組件,子組件通過聲明 props 來接收這些數據。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<div id="app">
  <!-- 傳遞數據到子組件 -->
  <child-component :message="parentMessage"></child-component>
</div>

<script>
const app = Vue.createApp({
  data() {
    return {
      parentMessage: 'Hello from the parent component!'
    };
  },
  components: {
    'child-component': {
      props: ['message'],
      template: '<p></p>'
    }
  }
});

app.mount('#app');
</script>

在這裡,父組件透過 :message="parentMessage"parentMessage 的值傳遞給子組件,子組件通過 props 接收並顯示這個值。

2. 子組件向父組件傳遞事件(emit)

子組件可以使用 $emit 來向父組件傳遞事件,父組件可以監聽這些事件來執行相應的邏輯。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<div id="app">
  <child-component @child-clicked="handleClick"></child-component>
</div>

<script>
const app = Vue.createApp({
  methods: {
    handleClick() {
      alert('Child component clicked!');
    }
  },
  components: {
    'child-component': {
      template: '<button @click="$emit(\'child-clicked\')">Click Me</button>'
    }
  }
});

app.mount('#app');
</script>

在這個例子中,子組件透過 $emit('child-clicked') 觸發事件,父組件通過 @child-clicked 監聽該事件,並在事件觸發時執行 handleClick 方法。


4. 組件間的通信方式

除了使用 props$emit 進行父子組件之間的數據傳遞,Vue 3 還提供了一些其他的通信方式:

1. 透過插槽(slot)進行內容分發

插槽允許我們在父組件中傳遞 HTML 結構到子組件中,這種方式特別適合定製化內容的需求。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<div id="app">
  <child-component>
    <p>This is a custom content from the parent!</p>
  </child-component>
</div>

<script>
const app = Vue.createApp({
  components: {
    'child-component': {
      template: `
        <div>
          <h2>Default content from child component</h2>
          <slot></slot>
        </div>
      `
    }
  }
});

app.mount('#app');
</script>

在這裡,<slot> 是子組件中的占位符,父組件可以在 <child-component> 中插入自定義內容,這些內容將替代插槽的內容。

2. 使用 provideinject

provideinject 用於跨層級傳遞數據。provide 在祖先組件中提供數據,inject 在後代組件中接收數據,這樣即使兩個組件不在直接的父子關係中,也可以實現數據共享。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<div id="app">
  <parent-component></parent-component>
</div>

<script>
const ChildComponent = {
  inject: ['sharedData'],
  template: '<p>Injected data: </p>'
};

const ParentComponent = {
  components: { ChildComponent },
  provide() {
    return {
      sharedData: 'Hello from provide!'
    };
  },
  template: '<child-component></child-component>'
};

const app = Vue.createApp({
  components: {
    'parent-component': ParentComponent
  }
});

app.mount('#app');
</script>

在這個例子中,祖先組件使用 provide 提供了 sharedData,而後代組件通過 inject 注入了這個數據並顯示出來。


5. 組件的生命周期

組件同樣擁有和 Vue 實例相似的生命週期鉤子,如 beforeMountmountedbeforeUpdate 等。這些鉤子允許我們在不同的生命週期階段對組件進行操作。

1
2
3
4
5
6
const ChildComponent = {
  template: '<p>Hello from the child component!</p>',
  mounted() {
    console.log('Child component has been mounted');
  }
};

總結

  • 組件 是 Vue 應用中的基本單位,能夠讓我們將應用分解成小的、可重用的模塊。
  • 我們可以全局或局部註冊組件,並且可以通過 props 傳遞數據,使用 $emit 傳遞事件。
  • 組件還支持插槽、自定義內容、provideinject,這些功能讓組件之間的通信變得更加靈活。
  • 每個組件都有自己的生命週期,允許我們在特定的階段執行代碼。

這些特性讓 Vue 的組件系統非常強大且靈活,適合用來構建各種規模的應用。

本文章以 CC BY 4.0 授權