最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Vue3 子傳父全解析實戰(zhàn)

 更新時間:2026年02月18日 09:31:06   作者:不想禿頭的程序員  
組件通信是繞不開的核心場景,而子傳父作為最基礎(chǔ)、最常用的通信方式之一,更是新手入門必掌握的知識點,文中通過代碼介紹的非常詳細,需要的朋友可以參考下

在 Vue3 開發(fā)中,組件通信是繞不開的核心場景,而子傳父作為最基礎(chǔ)、最常用的通信方式之一,更是新手入門必掌握的知識點。不同于 Vue2 的 $emit 寫法,Vue3 組合式 API(<script setup>)簡化了子傳父的實現(xiàn)邏輯,但也有不少細節(jié)和進階技巧需要注意。

本文將拋開 TypeScript,用最通俗的語言 + 可直接復(fù)制的實戰(zhàn)代碼,從基礎(chǔ)用法、進階技巧、常見場景到避坑指南,全方位講解 Vue3 子傳父,新手看完就能上手,老手也能查漏補缺。

一、核心原理:子組件觸發(fā)事件,父組件監(jiān)聽事件

Vue3 子傳父的核心邏輯和 Vue2 一致:子組件通過觸發(fā)自定義事件,將數(shù)據(jù)傳遞給父組件;父組件通過監(jiān)聽該自定義事件,接收子組件傳遞的數(shù)據(jù)。

關(guān)鍵區(qū)別在于:Vue3 <script setup> 中,無需通過 this.$emit 觸發(fā)事件,而是通過 defineEmits 聲明事件后,直接調(diào)用 emit 函數(shù)即可,語法更簡潔、更直觀。

先記住核心流程,再看具體實現(xiàn):

  1. 子組件:用 defineEmits 聲明要觸發(fā)的自定義事件(可選但推薦);
  2. 子組件:在需要傳值的地方(如點擊事件、接口回調(diào)),調(diào)用 emit('事件名', 要傳遞的數(shù)據(jù));
  3. 父組件:在使用子組件的地方,通過 @事件名="處理函數(shù)" 監(jiān)聽事件;
  4. 父組件:在處理函數(shù)中,接收子組件傳遞的數(shù)據(jù)并使用。

二、基礎(chǔ)用法:最簡潔的子傳父實現(xiàn)(必學)

我們用一個「子組件輸入內(nèi)容,父組件實時顯示」的簡單案例,講解基礎(chǔ)用法,代碼可直接復(fù)制到項目中運行。

1. 子組件(Child.vue):聲明事件 + 觸發(fā)事件

<template>
  <div class="child">
    <h4>我是子組件</h4>
    <!-- 輸入框輸入內(nèi)容,觸發(fā)input事件,傳遞輸入值 -->
    <input 
      type="text" 
      v-model="childInput" 
      @input="handleInput"
      placeholder="請輸入要傳遞給父組件的內(nèi)容"
    />
    <!-- 按鈕點擊,傳遞固定數(shù)據(jù) -->
    <button @click="handleClick" style="margin-top: 10px;">
      點擊向父組件傳值
    </button>
  </div>
</template>

<script setup>
// 1. 聲明要觸發(fā)的自定義事件(數(shù)組形式,元素是事件名)
// 可選,但推薦聲明:增強代碼可讀性,IDE會有語法提示,避免拼寫錯誤
const emit = defineEmits(['inputChange', 'btnClick'])

// 子組件內(nèi)部數(shù)據(jù)
const childInput = ref('')

// 輸入框變化時,觸發(fā)事件并傳遞輸入值
const handleInput = () => {
  // 2. 觸發(fā)事件:第一個參數(shù)是事件名,第二個參數(shù)是要傳遞的數(shù)據(jù)(可選,可多個)
  emit('inputChange', childInput.value)
}

// 按鈕點擊時,觸發(fā)事件并傳遞固定對象
const handleClick = () => {
  emit('btnClick', {
    name: '子組件',
    msg: '這是子組件通過點擊按鈕傳遞的數(shù)據(jù)'
  })
}
</script>

2. 父組件(Parent.vue):監(jiān)聽事件 + 接收數(shù)據(jù)

<template>
  <div class="parent">
    <h3>我是父組件</h3>
    <p>子組件輸入的內(nèi)容:{{ parentMsg }}</p>
    <p>子組件點擊傳遞的數(shù)據(jù):{{ parentData }}</p>
    
    <!-- 3. 監(jiān)聽子組件聲明的自定義事件,綁定處理函數(shù) -->
    <Child 
      @inputChange="handleInputChange"
      @btnClick="handleBtnClick"
    />
  </div>
</template>

<script setup>
// 引入子組件
import Child from './Child.vue'
import { ref, reactive } from 'vue'

// 父組件接收數(shù)據(jù)的容器
const parentMsg = ref('')
const parentData = reactive({
  name: '',
  msg: ''
})

// 4. 處理子組件觸發(fā)的inputChange事件,接收傳遞的數(shù)據(jù)
const handleInputChange = (val) => {
  // val 就是子組件emit傳遞過來的值(childInput.value)
  parentMsg.value = val
}

// 處理子組件觸發(fā)的btnClick事件,接收傳遞的對象
const handleBtnClick = (data) => {
  // data 是子組件傳遞的對象,直接解構(gòu)或賦值即可
  parentData.name = data.name
  parentData.msg = data.msg
}
</script>

3. 核心細節(jié)說明

  • defineEmits 是 Vue3 內(nèi)置的宏,無需導(dǎo)入,可直接使用;
  • emit 函數(shù)的第一個參數(shù)必須和 defineEmits 中聲明的事件名一致(大小寫敏感),否則父組件無法監(jiān)聽到;
  • emit 可傳遞多個參數(shù),比如 emit('event', val1, val2),父組件處理函數(shù)可對應(yīng)接收 (val1, val2) => {};
  • 父組件監(jiān)聽事件時,可使用 @事件名(簡寫)或 v-on:事件名(完整寫法),效果一致。

三、進階用法:優(yōu)化子傳父的體驗(實戰(zhàn)常用)

基礎(chǔ)用法能滿足簡單場景,但在實際開發(fā)中,我們還會遇到「事件校驗」「雙向綁定」「事件命名規(guī)范」等需求,這部分進階技巧能讓你的代碼更規(guī)范、更健壯。

1. 事件校驗:限制子組件傳遞的數(shù)據(jù)類型

通過 defineEmits 的對象形式,可對事件傳遞的數(shù)據(jù)進行類型校驗,避免子組件傳遞錯誤類型的數(shù)據(jù),提升代碼可靠性(類似 props 校驗)。

<script setup>
// 對象形式聲明事件,key是事件名,value是校驗函數(shù)(參數(shù)是子組件傳遞的數(shù)據(jù),返回boolean)
const emit = defineEmits({
  // 校驗inputChange事件傳遞的數(shù)據(jù)必須是字符串
  inputChange: (val) => {
    return typeof val === 'string'
  },
  // 校驗btnClick事件傳遞的數(shù)據(jù)必須是對象,且包含name和msg屬性
  btnClick: (data) => {
    return typeof data === 'object' && 'name' in data && 'msg' in data
  }
})

// 若傳遞的數(shù)據(jù)不符合校驗,控制臺會報警告(不影響代碼運行,僅提示)
const handleInput = () => {
  emit('inputChange', 123) // 傳遞數(shù)字,不符合校驗,控制臺報警告
}
</script>

2. 雙向綁定:v-model 簡化子傳父(高頻場景)

很多時候,子傳父是為了「修改父組件的數(shù)據(jù)」,比如表單組件、開關(guān)組件,這時可使用 v-model 簡化代碼,實現(xiàn)父子組件雙向綁定,無需手動聲明事件和處理函數(shù)。

Vue3 中,v-model 本質(zhì)是「語法糖」,等價于 :modelValue="xxx" @update:modelValue="xxx = $event"。

優(yōu)化案例:子組件開關(guān),父組件顯示狀態(tài)

<!-- 子組件(Child.vue) -->
<template>
  <div class="child">
    <h4>子組件開關(guān)</h4>
    <button @click="handleSwitch">
      {{ isOpen ? '關(guān)閉' : '打開' }}
    </button>
  </div>
</template>

<script setup>
// 1. 接收父組件通過v-model傳遞的modelValue
const props = defineProps(['modelValue'])
// 2. 聲明update:modelValue事件(固定命名,不可修改)
const emit = defineEmits(['update:modelValue'])

// 子組件內(nèi)部使用父組件傳遞的值
const isOpen = computed(() => props.modelValue)

// 開關(guān)切換,觸發(fā)事件,修改父組件數(shù)據(jù)
const handleSwitch = () => {
  emit('update:modelValue', !isOpen.value)
}
</script>
<!-- 父組件(Parent.vue) -->
<template>
  <div class="parent">
    <h3>父組件:{{ isSwitchOpen ? '開關(guān)已打開' : '開關(guān)已關(guān)閉' }}</h3>
    <!-- 直接使用v-model,無需手動監(jiān)聽事件 -->
    <Child v-model="isSwitchOpen" />
  </div>
</template>

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

const isSwitchOpen = ref(false)
</script>

擴展:多個 v-model 雙向綁定

Vue3 支持給同一個子組件綁定多個 v-model,只需給 v-model 加后綴,對應(yīng)子組件的propsemit 即可。

<!-- 父組件 -->
<Child 
  v-model:name="parentName" 
  v-model:age="parentAge" 
/>

<!-- 子組件 -->
<script setup>
// 接收多個v-model傳遞的props
const props = defineProps(['name', 'age'])
// 聲明對應(yīng)的update事件
const emit = defineEmits(['update:name', 'update:age'])

// 觸發(fā)事件修改父組件數(shù)據(jù)
emit('update:name', '新名字')
emit('update:age', 25)
</script>

3. 事件命名規(guī)范:提升代碼可讀性

在實際開發(fā)中,遵循統(tǒng)一的事件命名規(guī)范,能讓團隊協(xié)作更高效,推薦以下規(guī)范:

  • 事件名采用「kebab-case 短橫線命名」(和 HTML 事件命名一致),比如 input-change 而非 inputChange;
  • 事件名要語義化,體現(xiàn)事件的用途,比如 form-submit(表單提交)、delete-click(刪除點擊);
  • 雙向綁定的事件固定為 update:xxx,xxx 對應(yīng) props 名,比如 update:nameupdate:visible。

四、實戰(zhàn)場景:子傳父的常見應(yīng)用

結(jié)合實際開發(fā)中的高頻場景,給大家補充 3 個常用案例,覆蓋大部分子傳父需求。

場景1:子組件表單提交,父組件接收表單數(shù)據(jù)

<!-- 子組件(FormChild.vue) -->
<template>
  <div class="form-child">
    <input v-model="form.name" placeholder="請輸入姓名" />
    <input v-model="form.age" type="number" placeholder="請輸入年齡" />
    <button @click="handleSubmit">提交表單</button>
  </div>
</template>

<script setup>
import { reactive } from 'vue'

const emit = defineEmits(['form-submit'])

const form = reactive({
  name: '',
  age: ''
})

const handleSubmit = () => {
  // 表單校驗(簡化)
  if (!form.name || !form.age) return alert('請?zhí)顚懲暾畔?)
  // 提交表單數(shù)據(jù)給父組件
  emit('form-submit', form)
  // 提交后重置表單
  form.name = ''
  form.age = ''
}
</script>

場景2:子組件關(guān)閉彈窗,父組件控制彈窗顯示/隱藏

<!-- 子組件(ModalChild.vue) -->
<template>
  <div class="modal" v-if="visible">
    <div class="modal-content">
      <h4>子組件彈窗</h4>
      <button @click="handleClose">關(guān)閉彈窗</button>
    </div>
  </div>
</template>

<script setup>
const props = defineProps(['visible'])
const emit = defineEmits(['close-modal'])

const handleClose = () => {
  // 觸發(fā)關(guān)閉事件,通知父組件隱藏彈窗
  emit('close-modal')
}
</script>

場景3:子組件列表刪除,父組件更新列表

<!-- 子組件(ListChild.vue) -->
<template>
  <div class="list-child">
    <div v-for="item in list" :key="item.id">
      {{ item.name }}
      <button @click="handleDelete(item.id)">刪除</button>
    </div>
  </div>
</template>

<script setup>
const props = defineProps(['list'])
const emit = defineEmits(['delete-item'])

const handleDelete = (id) => {
  // 傳遞要刪除的id給父組件,由父組件更新列表
  emit('delete-item', id)
}
</script>

五、常見坑點避坑指南(新手必看)

很多新手在寫子傳父時,會遇到「父組件監(jiān)聽不到事件」「數(shù)據(jù)傳遞失敗」等問題,以下是最常見的 4 個坑點,幫你快速避坑。

坑點1:事件名大小寫不一致

子組件 emit('inputChange'),父組件 @inputchange="handle"(小寫),會導(dǎo)致父組件監(jiān)聽不到事件。

解決方案:統(tǒng)一采用 kebab-case 命名,子組件 emit('input-change'),父組件 @input-change="handle"。

坑點2:忘記聲明事件(defineEmits)

子組件直接調(diào)用 emit('event'),未用 defineEmits 聲明事件,雖然開發(fā)環(huán)境可能不報錯,但生產(chǎn)環(huán)境可能出現(xiàn)異常,且 IDE 無提示。

解決方案:無論事件是否需要校驗,都用 defineEmits 聲明(數(shù)組形式即可)。

坑點3:傳遞復(fù)雜數(shù)據(jù)(對象/數(shù)組)時,父組件修改后影響子組件

子組件傳遞對象/數(shù)組給父組件,父組件直接修改該數(shù)據(jù),會影響子組件(因為引用類型傳遞的是地址)。

解決方案:父組件接收數(shù)據(jù)后,用 JSON.parse(JSON.stringify(data)) 深拷貝,或用 reactive + toRaw 處理,避免直接修改原始數(shù)據(jù)。

坑點4:v-model 雙向綁定時報錯,提示「modelValue 未定義」

原因:子組件未接收 modelValue props,或未聲明 update:modelValue 事件。

解決方案:確保子組件 defineProps(['modelValue'])defineEmits(['update:modelValue']) 都聲明。

六、總結(jié):子傳父核心要點回顧

Vue3 子傳父的核心就是「事件觸發(fā) + 事件監(jiān)聽」,記住以下 3 個核心要點,就能應(yīng)對所有場景:

  1. 基礎(chǔ)寫法:defineEmits 聲明事件 → emit 觸發(fā)事件 → 父組件 @事件名 監(jiān)聽;
  2. 進階優(yōu)化:事件校驗提升可靠性,v-model 簡化雙向綁定,遵循 kebab-case 命名規(guī)范;
  3. 避坑關(guān)鍵:事件名大小寫一致、必聲明事件、復(fù)雜數(shù)據(jù)深拷貝、v-model 對應(yīng) props 和 emit 命名正確。

子傳父是 Vue3 組件通信中最基礎(chǔ)的方式,掌握它之后,再學習父傳子(props)、跨層級通信(provide/inject)、全局通信(Pinia)會更輕松。

到此這篇關(guān)于Vue3 子傳父全解析實戰(zhàn)的文章就介紹到這了,更多相關(guān)Vue3 子傳父內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • VUEJS實戰(zhàn)之修復(fù)錯誤并且美化時間(2)

    VUEJS實戰(zhàn)之修復(fù)錯誤并且美化時間(2)

    這篇文章主要為大家詳細介紹了VUEJS實戰(zhàn)之修復(fù)錯誤并且美化時間,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-06-06
  • vue下使用fullcalendar案例講解

    vue下使用fullcalendar案例講解

    這篇文章主要介紹了vue下使用fullcalendar及簡單案例,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2024-01-01
  • Vue2 添加數(shù)據(jù)可視化支持的方法步驟

    Vue2 添加數(shù)據(jù)可視化支持的方法步驟

    這篇文章主要介紹了Vue2 添加數(shù)據(jù)可視化支持的方法步驟,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-01-01
  • vue 父組件通過$refs獲取子組件的值和方法詳解

    vue 父組件通過$refs獲取子組件的值和方法詳解

    今天小編就為大家分享一篇vue 父組件通過$refs獲取子組件的值和方法詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-11-11
  • elementui實現(xiàn)表格自定義排序的示例代碼

    elementui實現(xiàn)表格自定義排序的示例代碼

    本文主要介紹了elementui實現(xiàn)表格自定義排序的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-07-07
  • vue和react中關(guān)于插槽詳解

    vue和react中關(guān)于插槽詳解

    這篇文章主要介紹了vue和react中關(guān)于插槽詳解,slot插槽是Vue對組件嵌套這種擴展機制的稱謂,在react可以也這樣稱呼,但是并不很常見。不過叫slot確實很形象
    2022-08-08
  • el-select 點擊按鈕滾動到選擇框頂部的實現(xiàn)代碼

    el-select 點擊按鈕滾動到選擇框頂部的實現(xiàn)代碼

    本文通過實例代碼給大家分享el-select 點擊按鈕滾動到選擇框頂部效果,主要代碼是在visibleChange在這個popper里面找到.el-select-dropdown__list,感興趣的朋友跟隨小編一起看看吧
    2024-05-05
  • Vue打包后訪問靜態(tài)資源路徑問題

    Vue打包后訪問靜態(tài)資源路徑問題

    在本篇文章里小編給各位整理的是關(guān)于Vue打包后訪問靜態(tài)資源路徑問題相關(guān)知識點,需要的朋友們學習下。
    2019-11-11
  • 淺析webpack-bundle-analyzer在vue-cli3中的使用

    淺析webpack-bundle-analyzer在vue-cli3中的使用

    這篇文章主要介紹了webpack-bundle-analyzer在vue-cli3中的使用,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-10-10
  • Vue實現(xiàn)倒計時小功能

    Vue實現(xiàn)倒計時小功能

    這篇文章主要為大家詳細介紹了Vue實現(xiàn)倒計時小功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-09-09

最新評論

望谟县| 三河市| 赣榆县| 连江县| 龙山县| 玛沁县| 友谊县| 定日县| 凌源市| 福海县| 塘沽区| 容城县| 克什克腾旗| 中山市| 灵宝市| 天台县| 措勤县| 商丘市| 澄城县| 万州区| 民权县| 磐石市| 麻城市| 涟水县| 隆回县| 津市市| 凤翔县| 三穗县| 时尚| 鄂尔多斯市| 泸州市| 旬邑县| 永福县| 石阡县| 措勤县| 彭州市| 澜沧| 兴国县| 民县| 思茅市| 涞水县|