父子組件進行數據雙向綁定 - daniel-qa/Vue GitHub Wiki

父子組件進行數據雙向綁定


在 Vue 3 中,defineProps 和 defineEmits 是兩個非常重要的 API,它們主要用於父子組件之間的溝通。

defineProps

作用: 用於在子組件中聲明 props,props 是父組件傳遞給子組件的數據。

使用方式: 在 <script setup> 語法糖中,直接使用 defineProps() 函數。

參數: 可以是一個物件,也可以是一個泛型。

  • 範例一:物件形式
<template>
  <div>
    <p>姓名:{{ name }}</p>
    <p>年齡:{{ age }}</p>
  </div>
</template>

<script setup>
const props = defineProps({
  name: String,
  age: Number
})

console.log(props.name) // 訪問父組件傳遞的 name
console.log(props.age) // 訪問父組件傳遞的 age
</script>
  • 範例二:泛型形式 (Typescript)
<template>
  <div>
    <p>姓名:{{ name }}</p>
    <p>年齡:{{ age }}</p>
  </div>
</template>

<script setup lang="ts">
import { defineProps } from 'vue'

interface Props {
  name: string
  age: number
}

const props = defineProps<Props>()

console.log(props.name) // 訪問父組件傳遞的 name
console.log(props.age) // 訪問父組件傳遞的 age
</script>

defineEmits

作用: 用於在子組件中觸發自定義事件,父組件可以監聽這些事件並執行相應的操作。

使用方式: 在 <script setup> 語法糖中,直接使用 defineEmits() 函數。

參數: 可以是一個陣列,也可以是一個物件。

  • 範例一:陣列形式
<template>
  <button @click="handleClick">點擊觸發事件</button>
</template>

<script setup>
const emit = defineEmits(['my-event'])

const handleClick = () => {
  emit('my-event', 'Hello from child!') // 觸發 my-event 事件,並傳遞參數
}
</script>
  • 範例二:物件形式
<template>
  <button @click="handleClick">點擊觸發事件</button>
</template>

<script setup>
const emit = defineEmits({
  'my-event': (data: string) => {
    return true // 返回 true 表示驗證通過
  }
})

const handleClick = () => {
  emit('my-event', 'Hello from child!') // 觸發 my-event 事件,並傳遞參數
}
</script>
  • 父組件如何使用
<template>
  <MyComponent 
    name="John" 
    age="30" 
    @my-event="handleMyEvent" 
  />
</template>

<script setup>
import MyComponent from './MyComponent.vue'

const handleMyEvent = (data) => {
  console.log('Received from child:', data)
}
</script>
  • 總結

defineProps 和 defineEmits 是 Vue 3 中非常重要的兩個 API,它們使得父子組件之間的溝通變得更加清晰和簡單。透過 defineProps,父組件可以將數據傳遞給子組件;透過 defineEmits,子組件可以將事件傳遞給父組件。


多個綁定的寫法

  • 父組件要添加的部分
<template>
  <div>
    <ChildComponent 
      v-model:searchQuery="searchQuery"
      v-model:activeIndex="activeIndex"
      v-model:activeIndex2="activeIndex2"
    />
    <p>搜索关键字: {{ searchQuery }}</p>
    <p>激活索引1: {{ activeIndex }}</p>
    <p>激活索引2: {{ activeIndex2 }}</p>
  </div>
</template>

<script setup>
import { ref } from 'vue';
import ChildComponent from './ChildComponent.vue';

const searchQuery = ref('');
const activeIndex = ref(0);
const activeIndex2 = ref(0);
</script>
  • 子組件要添加的部分
// 雙向綁定的設定
const emit = defineEmits([
    'update:searchQuery',
    'update:activeIndex',
    'update:activeIndex2'
]);

const updateSearchQuery = (event) => {
    emit('update:searchQuery', event.target.value); // 更新父组件中的 searchQuery
};

const updateActiveIndex = (index) => {
    emit('update:activeIndex', index); // 更新父组件中的 activeIndex
};

const updateActiveIndex2 = (index) => {
    emit('update:activeIndex2', index); // 更新父组件中的 activeIndex2
};
⚠️ **GitHub.com Fallback** ⚠️