揭秘:父子組件之間的傳遞

基礎知識

組件與組件之間有三大方面的知識點:

  • 子組件通過props = defineProps({})接收父組件傳遞到參數和方法;
  • 子組件可以通過定義 emit 事件,向父組件發送事件;
  • 父組件調用子組件通過defineExpose 導出的方法

一、props==>接收父組件的參數和方法

子組件通過props = defineProps({})可以接收父組件傳來的變量參數和方法;

示例如下:

const props = defineProps({page: number, //v-model:page vue3中的v-model新特性,支持多個v-model的數據綁定total:number, //普通傳遞參數queryParams: {   // 初始表單數據type: Object,default: () => ({processor: '',remark: ''})},getList: {  //父組件方法type: Function,default: () => {}});

父組件傳遞的方法和參數 ,具體示例如下:假設子組件為TabComponent

<TabComponent v-model:page="pageValue" ref="LegShippingPlanTabComponent" :total="total" :queryParams="queryParams" :getList="getList" />

總結:父組件通過“ : ”向子組件傳遞參數和方法,子組件通過props = defineProps({}),后期子組件直接通過 prop.page 使用參數

示例如下:

props.queryParams.pageNum = 1;
props.queryParams.planStatus = pane.paneName;
props.getList(); //使用父組件方法

二、emit==>向父組件發出 emit 事件(參數和方法事件)

子組件定義 emit 事件,在需要的地方調用 emit 事件向父組件發出 emit 事件;

事件可以分為兩種一個是參數,一個是方法

案例一:v-model:propName 類型,實現數據的雙向綁定

父組件

<TabComponent v-model:page="pageValue" ref="LegShippingPlanTabComponent" :queryParams="queryParams" :getList="getList" />

拓展知識點

這是 vue3 中的 v-model 中的新特性:

  • Vue 3 允許自定義組件有多個 v-model 綁定,語法格式為 v-model:propName
  • 默認 v-model (綁定到 modelValue):

子組件

先通過props = defineProps({})接收到數據,然后定義 emit()更新事件

const props = defineProps({total: propTypes.number,page: propTypes.number.def(1),limit: propTypes.number.def(20),pageSizes: {type: Array as PropType<number[]>,default: () => [10, 20, 30, 50]},
})
const emit = defineEmits(['update:page']);
//向父組件發出emit事件
const save=()=>{emit('update:page', val); //update:page發出這個事件,val是page的值;
}

總結:這里就實現了 父子組件的雙向綁定;

案例二:子組件通過 emit 發送方法事件

子組件:

首先定義 emit 事件,然后調用 emit 發送事件

const props = defineProps({total: propTypes.number,page: propTypes.number.def(1),limit: propTypes.number.def(20),pageSizes: { //小駝峰type: Array as PropType<number[]>,default: () => [10, 20, 30, 50]}
});
const emit = defineEmits(['pagination']);
//發送emit事件,不傳遞參數
const handleAdd=()=>{emit('pagination')
}
//發送emit事件 可以傳遞參數
const handleSubmit=()=>{emit('pagination', { page: val, limit: pageSize.value });
}

父組件:

通過@ pagination 接收,父組件中的這個 pagination 的名字需要與子組件中的 emit 事件名稱一樣及const emit = defineEmits(['pagination']);

<pagination
:total="total"
v-model:page="queryParams.pageNum"
v-model:limit="queryParams.pageSize"
@pagination="getList"
:page-sizes="[10, 20, 50, 100, 500, 1000, 2000]"/>

總結:分為三步,一是子組件中定義emit事件;二是發出emit事件;三父組件通過@pagination響應


三、defineExpose

父組件調用子組件通過defineExpose 導出的方法)

子組件

通過defineExpose 導出(暴露)子組件的方法

<script setup name="LegShippingPlanTabComponent" lang="ts">
const getTabStatusCount = async () => {const res = await getTabCount();activeTabCount.value = res.data;
}defineExpose({getTabStatusCount,
})
</script>

父組件:

先定義一個 ref,然后通過.vale.getTabStatusCount()直接調用子組件的方法;

<TabComponent ref="LegShippingPlanTabComponent" :queryParams="queryParams" :getList="getList" />
<script setup name="LegShippingPlan" lang="ts">const LegShippingPlanTabComponent = ref()
/** 查詢頭程發貨計劃列表 */
const getList = async () => {await LegShippingPlanTabComponent.value.getTabStatusCount();
}</script>

總結:如果父組件需要用子組件defineExpose的方法,一定要在使用這個子組件中加一個 ref,通過它去調用子組件的方法;


四、實戰案例

子組件

<script setup>
import { ref, watch } from 'vue';const props = defineProps({modelValue: Boolean, // 控制彈窗顯示initialFormData: {   // 初始表單數據type: Object,default: () => ({processor: '',remark: ''})}
});const emit = defineEmits(['update:modelValue', 'submit']);// 表單數據
const paramsForm = ref({ ...props.initialFormData });// 表單引用(用于驗證)
const formRef = ref(null);// 監聽彈窗打開時重置表單
watch(() => props.modelValue, (visible) => {if (visible) {paramsForm.value = { ...props.initialFormData };}
});// 提交表單
const handleSubmit = async () => {try {// 表單驗證await formRef.value.validate();// 提交數據并關閉彈窗emit('submit', { ...paramsForm.value });emit('update:modelValue', false);} catch (error) {console.error('表單驗證失敗:', error);}
};// 關閉彈窗
const closeDialog = () => {emit('update:modelValue', false);
};
</script><template><el-dialog:model-value="modelValue"@update:model-value="$emit('update:modelValue', $event)"title="轉交處理人"width="500px"><el-formref="formRef":model="paramsForm"label-width="80px":rules="{processor: [{ required: true, message: '請選擇處理人', trigger: 'blur' }]}"><el-form-item label="處理人" prop="processor"><el-selectv-model="paramsForm.processor"placeholder="請選擇處理人"style="width: 100%"><el-option label="張三" value="zhangsan" /><el-option label="李四" value="lisi" /><el-option label="王五" value="wangwu" /></el-select></el-form-item><el-form-item label="備注"><el-inputv-model="paramsForm.remark"type="textarea"placeholder="請輸入備注信息"/></el-form-item></el-form><template #footer><el-button @click="closeDialog">取消</el-button><el-button type="primary" @click="handleSubmit">確定</el-button></template></el-dialog>
</template>

父組件

<script setup>
import { ref } from 'vue';
import { ElMessage } from 'element-plus';
import ChildDialog from './ChildDialog.vue';
import { updateProcessor } from '@/api/your-api'; // 替換為你的API// 控制彈窗顯示
const dialogVisible = ref(false);// 父組件表單數據
const formData = ref({id: '',       // 假設有ID字段title: '',    // 其他表單字段processor: '', // 處理人remark: ''    // 備注
});// 打開彈窗
const openTransferDialog = () => {dialogVisible.value = true;
};// 接收子組件數據并發請求
const handleSubmit = async (transferData) => {try {// 1. 更新本地表單數據formData.value.processor = transferData.processor;formData.value.remark = transferData.remark;// 2. 調用API更新處理人const res = await updateProcessor({id: formData.value.id,processor: transferData.processor,remark: transferData.remark});// 3. 提示成功ElMessage.success('處理人更新成功');// 4. 可以在這里刷新數據或執行其他操作// fetchData();} catch (error) {ElMessage.error('更新處理人失敗: ' + error.message);console.error('API請求錯誤:', error);}
};
</script><template><div class="parent-container"><!-- 主表單 --><el-form :model="formData" label-width="100px"><el-form-item label="標題"><el-input v-model="formData.title" disabled /></el-form-item><el-form-item label="當前處理人"><el-input v-model="formData.processor" disabled /></el-form-item><el-form-item><el-button type="primary" @click="openTransferDialog">轉交處理人</el-button></el-form-item></el-form><!-- 子組件彈窗 --><ChildDialogv-model="dialogVisible"@submit="handleSubmit":initial-form-data="{processor: formData.processor,remark: formData.remark}"/></div>
</template><style scoped>
.parent-container {padding: 20px;max-width: 800px;margin: 0 auto;
}
</style>

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/899679.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/899679.shtml
英文地址,請注明出處:http://en.pswp.cn/news/899679.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

微前端實現方案對比Qiankun VS npm組件

架構層面&#xff1a; 1、Qiankun是典型的微前端架構&#xff0c;側重構建多個獨立前端應用協同工作的架構&#xff0c;主應用負責自用用的加載、卸載和通信&#xff1b;子應用不限制&#xff0c;可以是VUE、React等&#xff1b; 2、Qiankun松耦合&#xff0c;各個自應用獨立…

可編輯160頁PPT | 營銷流程和管理數字化轉型規劃

薦言分享&#xff1a;隨著技術的發展和消費者行為的變化&#xff0c;傳統營銷方式已難以滿足現代企業的需求。企業需要借助數字化手段&#xff0c;對營銷流程進行全面梳理和優化&#xff0c;提升營銷活動的精準度和效率。同時&#xff0c;通過數字化營銷管理&#xff0c;企業可…

Ecovadis認證需要準備哪些材料?

Ecovadis認證&#xff0c;作為全球領先的企業社會責任&#xff08;CSR&#xff09;評估平臺&#xff0c;其準備材料的過程不僅需要詳盡無遺&#xff0c;更要體現出企業在環境、社會、勞工和倫理四大方面的卓越實踐與持續改進的決心。 首先&#xff0c;環境管理方面&#xff0c…

程序化廣告行業(45/89):RTB競價后續流程、結算規則及相關要點解讀

程序化廣告行業&#xff08;45/89&#xff09;&#xff1a;RTB競價后續流程、結算規則及相關要點解讀 大家好&#xff01;一直以來&#xff0c;我都希望能和大家一起在程序化廣告這個領域不斷探索、共同成長&#xff0c;這也是我寫這系列博客的初衷。之前我們了解了程序化廣告…

權重參數矩陣

目錄 1. 權重參數矩陣的定義與作用 2. 權重矩陣的初始化與訓練 3. 權重矩陣的解讀與分析 (1) 可視化權重分布 (2) 統計指標分析 4. 權重矩陣的常見問題與優化 (1) 過擬合與欠擬合 (2) 梯度問題 (3) 權重對稱性問題 5. 實際應用示例 案例1&#xff1a;全連接網絡中的…

文法 2025/3/3

文法的定義 一個文法G是一個四元組&#xff1a;G(,,S,P) &#xff1a;一個非空有限的終極符號集合。它的每個元素稱為終極符號或終極符&#xff0c;一般用小寫字母表示。終極符號是一個語言不可再分的基本符號。 &#xff1a;一個非空有限的非終極符號集合。它的每個元素稱為…

字符串復習

344:反轉字符串 編寫一個函數&#xff0c;其作用是將輸入的字符串反轉過來。輸入字符串以字符數組 s 的形式給出。 不要給另外的數組分配額外的空間&#xff0c;你必須原地修改輸入數組、使用 O(1) 的額外空間解決這一問題。 示例 1&#xff1a; 輸入&#xff1a;s ["…

【數據結構】算法效率的雙刃劍:時間復雜度與空間復雜度

前言 在算法的世界里&#xff0c;效率是衡量算法優劣的關鍵標準。今天&#xff0c;就讓我們深入探討算法效率的兩個核心維度&#xff1a;時間復雜度和空間復雜度&#xff0c;幫助你在算法設計的道路上更進一步。 一、算法效率&#xff1a;衡量算法好壞的關鍵 算法的效率主要…

Java基礎-26-多態-認識多態

在Java編程中&#xff0c;多態&#xff08;Polymorphism&#xff09; 是面向對象編程的核心概念之一。通過多態&#xff0c;我們可以編寫更加靈活、可擴展的代碼。本文將詳細介紹什么是多態、如何實現多態&#xff0c;并通過具體的例子來幫助你更好地理解這一重要概念。 一、什…

使用自定義的RTTI屬性對對象進行流操作

由于歷史原因&#xff0c;在借鑒某些特定出名的游戲引擎中&#xff0c;不知道當時的作者的意圖和編寫方式 特此做這篇文章。&#xff08;本文出自游戲編程精粹4 中 使用自定義的RTTI屬性對對象進行流操作 文章&#xff09; 載入和 保存 關卡&#xff0c;并不是一件容易辦到的事…

周總結aa

上周學習了Java中有關字符串的內容&#xff0c;與其有關的類和方法 學習了static表示靜態的相關方法和類的使用。 學習了繼承(extends) 多態&#xff08;有繼承關系&#xff0c;有父類引用指向子類對象&#xff09; 有關包的知識&#xff0c;final關鍵字的使用&#xff0c;及有…

密碼學基礎——密碼學相關概念

目錄 1.1 密碼系統&#xff08;Cryptosystem&#xff09; 1.2 密碼編碼學 1.3 密碼分析學 1.4 基于算法保密 1.5 基于密鑰保密 1.6密碼系統的設計要求 1.7 單鑰體制 1.8 雙鑰體制 密鑰管理 1.1 密碼系統&#xff08;Cryptosystem&#xff09; 也稱為密碼體制&#xff0…

初始JavaEE篇 —— Mybatis-plus 操作數據庫

找往期文章包括但不限于本期文章中不懂的知識點&#xff1a; 個人主頁&#xff1a;我要學編程程(?_?)-CSDN博客 所屬專欄&#xff1a;JavaEE 目錄 前言 Mybatis-plus 快速上手 Mybatis-plus 復雜操作 常用注解 TableName TableField TableId 打印日志 條件構造器 …

PyQt6實例_批量下載pdf工具_主線程啟用線程池

目錄 前置&#xff1a; 代碼&#xff1a; 視頻&#xff1a; 前置&#xff1a; 1 本系列將以 “PyQt6實例_批量下載pdf工具”開頭&#xff0c;放在 【PyQt6實例】 專欄 2 本系列涉及到的PyQt6知識點&#xff1a; 線程池&#xff1a;QThreadPool,QRunnable&#xff1b; 信號與…

1.2 斐波那契數列模型:LeetCode 面試題 08.01. 三步問題

動態規劃解三步問題&#xff1a;LeetCode 面試題 08.01. 三步問題 1. 題目鏈接 LeetCode 面試題 08.01. 三步問題 題目要求&#xff1a;小孩上樓梯&#xff0c;每次可以走1、2或3步&#xff0c;計算到達第 n 階臺階的不同方式數&#xff0c;結果需對 1e9 7 取模。 2. 題目描述…

UE5 學習筆記 FPS游戲制作30 顯示擊殺信息 水平框 UI模板(預制體)

文章目錄 一制作單條死亡信息框水平框的使用創建一個水平框添加子元素調整子元素順序子元素的布局插槽尺寸填充對齊 制作UI 根據隊伍&#xff0c;設置文本的名字和顏色聲明變量 將變量設置為構造參數根據隊伍&#xff0c;設置文本的名字和顏色在構造事件中&#xff0c;獲取玩家…

HTTP---基礎知識

天天開心&#xff01;&#xff01;&#xff01; 文章目錄 一、HTTP基本概念1. 什么是HTTP&#xff0c;又有什么用&#xff1f;2. 一次HTTP請求的過程3.HTTP的協議頭4.POST和GET的區別5. HTTP狀態碼6.HTTP的優缺點 二、HTTP的版本演進1.各個版本的應用場景2、注意要點 三、HTTP與…

數據結構 KMP 字符串匹配算法

KMP算法是計算機科學中的一種字符串匹配算法&#xff0c;KMP是三個創始人名字首字母 題目 AcWing - 算法基礎課 前置知識點 KMP算法是一種高效的字符串匹配算法&#xff0c;算法名稱取自于三位共同發明人名字的首字母組合。該算法的主要使用場景就是在字符串&#xff08;也叫…

Conda配置Python環境

1. 安裝 Conda 選擇發行版&#xff1a; Anaconda&#xff1a;適合需要預裝大量科學計算包的用戶&#xff08;體積較大&#xff09;。 Miniconda&#xff1a;輕量版&#xff0c;僅包含 Conda 和 Python&#xff08;推薦自行安裝所需包&#xff09;。 驗證安裝&#xff1a; co…

數倉開發那些事(11)

某神州優秀員工&#xff1a;一閃&#xff0c;領導說要給我漲米。 一閃&#xff1a;。。。。&#xff08;著急的團團轉&#xff09; 老運維&#xff1a;Oi&#xff0c;兩個吊毛&#xff0c;看看你們的hadoop集群&#xff0c;健康度30分&#xff0c;怎么還在抽思謀克&#xff1f…