Vue 系列之:組件通訊

子組件調用父組件方法

1、直接在子組件中通過 this.$parent.event 來調用父組件的方法

父組件:

<template><p><child></child></p>
</template>
<script>import child from './child';export default {components: {child},methods: {fatherMethod() {console.log('測試');}}};
</script>

子組件:

<template><p><button @click="childMethod()">點擊</button></p>
</template>
<script>export default {methods: {childMethod() {this.$parent.fatherMethod();}}};
</script>

2、父組件使用 v-on 監聽事件,子組件使用 $emit 件觸發事件

@ 是 v-on 的縮寫

父組件:

<template><p><child @method1="fatherMethod"></child></p>
</template>
<script>import child from './child';export default {components: {child},methods: {fatherMethod(params) {console.log('測試', params);}}};
</script>

子組件:

<template><p><button @click="childMethod()">點擊</button></p>
</template>
<script>export default {methods: {childMethod() {this.$emit('method1', params); // params 為參數,可不傳 // this.$emit('method1');}}};
</script>

3、父組使用 v-bind 綁定事件,子組件用 props 接收事件

: 是 v-bind 的縮寫

父組件:

<template><p><child :method1="fatherMethod"></child></p>
</template>
<script>import child from './child';export default {components: {child},methods: {fatherMethod() {console.log('測試');}}};
</script>

子組件:

<template><p><button @click="childMethod()">點擊</button></p>
</template>
<script>export default {props: {method1: {type: Function,default: null}},methods: {childMethod() {if (this.method1) {this.method1();}}}};
</script>

父組件調用子組件方法

1、通過 ref 直接調用子組件的方法

父組件:

<template><div><Button @click="fatherMethod">點擊調用子組件方法</Button><Child ref="child"/></div>
</template>    <script>
import Child from './child';
export default {methods: {fatherMethod() {this.$refs.child.childMethod();},},
}
</script>

子組件:

<template><div>我是子組件</div>
</template><script>
export default {methods: {childMethod() {console.log('我是子組件的方法');},},
};</script>

2、通過組件的$emit$on方法(可以,但是沒必要)

父組件:

<template><div><Button @click="fatherMethod">點擊調用子組件方法</Button><Child ref="child"/></div>
</template>    <script>
import Child from './child';
export default {methods: {fatherMethod() {this.$refs.child.$emit("getChildMethod")    //子組件$on中的名字},},
}
</script>

子組件:

<template><div>我是子組件</div>
</template><script>
export default {mounted() {this.$nextTick(function() {this.$on('getChildMethod', this.childMethod);});},methods: {childMethod() {console.log('我是子組件方法');}}
};
</script>

兄弟組件

  • 方法1:通過父組件作為中轉

    • 通過 ref 和 $parent

    • 通過 provide 和 inject

  • 方法2:使用 EventBus 事件總線

  • 方法3:vuex,下一篇內容會講

EventBus 使用方式

1、初始化——全局定義

可以將 eventBus 綁定到 vue 實例的原型上,也可以直接綁定到 window 對象上

//main.js//注冊方式一
Vue.prototype.$EventBus = new Vue();//注冊方式二
window.EventBus = new Vue();

2、監聽事件

//使用方式一
this.$EventBus.$on('eventName', (param1, param2, ...) => {//需要執行的代碼
})//使用方式二
EventBus.$on('eventName', (param1, param2, ...) => {//需要執行的代碼
})

3、觸發事件

//使用方式一
this.$EventBus.$emit('eventName', param1, param2,...)//使用方式二
EventBus.$emit('eventName', param1, param2,...)

4、移除監聽事件

為了避免在監聽時,事件被反復觸發,通常需要在頁面銷毀時移除事件監聽。或者在開發過程中,由于熱更新,事件可能會被多次綁定監聽,這時也需要移除事件監聽。

//使用方式一
this.$EventBus.$off('eventName');//使用方式二
EventBus.$off('eventName');//移除所有
EventBus.$off();

5、示例

簡單示例一:

<!--組件 A.vue-->
<script>
export default {  mounted() {  // 監聽事件this.$EventBus.$on('custom-event', this.handleEvent)  },  methods: {  handleEvent(data) {  console.log(data)  }  }  
}
</script><!--組件 B.vue-->
<template>  <button @click="handleClick">觸發事件</button>  
</template>  <script>
export default {data() {return {str: '我來自 B 組件'}}methods: {handleClick() {// 觸發事件this.$EventBus.$emit('custom-event', this.str)  }  }  
}  
</script>

示例二:

假設兄弟組件有三個,分別是 A、B、C 組件,A 組件如何獲取 B 或者 C 組件的數據

這時候就可以使用 EventBus。EventBus 是一種發布/訂閱模式,用于在組件之間傳遞事件和數據。A 組件可以監聽由 B 或 C 組件發布的事件,并在事件處理函數中獲取傳遞的數據。

思路:
A 組件中使用 Event.$on 監聽事件
B、C 組件中使用 Event.$emit 觸發事件

// A.vue  
<template>  <div>A 接收到的數據: {{ receivedData }}</div>  
</template>  <script>  export default {  data() {  return {  receivedData: null  };  },  mounted() {  // 監聽事件  EventBus.$on('custom-event', (data) => {  this.receivedData = data.message;  });  },  beforeDestroy() {  // 組件銷毀前,移除事件監聽器  EventBus.$off('custom-event');  }  
};  
</script>
// B.vue 和 C.vue
<template>  <button @click="sendData">發送數據</button>  
</template>  <script>  
export default {  methods: {sendData() {  const data = { message: 'I am from B' };// 觸發事件EventBus.$emit('data-from-a', data);  }  }  
};  
</script>

多層組件(爺孫)

provide() 和 inject[]

用于將數據或方法暴露給組件樹中的任何后代組件,哪怕是深層次的后代組件都可以訪問到這些數據,而無需通過 props 層層傳遞。

注意:provide 和 inject 主要用于單向數據傳遞,即從祖先組件流向后代組件。雖然可以在后代組件中修改注入的數據,但這種做法會破壞單向數據流的原則,導致數據流向不清晰,難以調試,因此不建議這樣做。

Vue2 用法:

<!--爺/父 組件-->
<template><div id="app"><Children></Children></div>
</template><script>
import Children from "./Children.vue";
export default {name: 'parent',components: { Children },provide() {return {parentEvent: this.myEvent,parentData: this.message,parentStr: '字符串數據'};},data() {return {message: 'data中的數據'}},methods: {myEvent(params1, params2) {console.log(params1, params2)},}
};
</script>
<!--子/孫 組件-->
<template><el-button @click="handleClick">測試</el-button>
</template><script>
export default {name: 'child',inject: ["parentEvent", "parentData", "parentStr"],methods: {handleClick() {this.parentEvent('參數1', '參數2');console.log(this.parentData)console.log(this.parentStr)}}
};
</script>

從上到下依次打印:

參數1 參數2
data中的數據
字符串數據

Vue3 用法:

<!--爺/父 組件-->
<template><div id="app"><Children></Children></div>
</template><script setup>
import { ref, provide } from "vue";
import Children from "./Children.vue";
const message = ref('data中的數據');
const str = '字符串數據'
function myEvent(params1, params2) {console.log(params1, params2)
}
provide('parentEvent', myEvent);
provide('parentData', message);
provide('parentStr', str);
</script>
<!--子/孫 組件-->
<template><el-button @click="handleClick">測試</el-button>
</template><script setup>
import { inject } from "vue";
const parentEvent = inject('parentEvent');
const parentData = inject('parentData');
const parentStr = inject('parentStr', '默認值');function handleClick() {parentEvent('參數1', '參數2')console.log(parentData.value)console.log(parentStr)
}
</script>

細心的朋友已經發現:在 Vue3 中,子組件打印的是 parentData.value,這說明 parentData 是一個響應式對象。

直接總結:

特性Vue2Vue3
響應式支持provide 提供的數據不是響應式provide 提供的數據是響應式
默認值支持不支持默認值支持默認值,inject 的第二個參數就是默認值

$attrs 和 $listeners

$attrs

$attrs 是一個對象,包含了父組件傳遞給子組件的所有非 prop 屬性(即沒有在 props 中定義的屬性)。

當你希望將父組件傳遞的屬性傳遞給子組件的子組件時,可以使用 $attrs。

父組件:

<!-- 父組件 -->
<template><div id="app"><Children :params1="params1" :params2="params2" /></div>
</template><script>
import Children from "./Children.vue";
export default {name: 'parent',components: { Children },data() {return {params1: '測試1',params2: '測試2',params3: '測試3',}},mounted() {setTimeout(() => {this.params2 += 'timeout'}, 5000);},
};
</script>

子組件:

<!-- 子組件 -->
<template><div><p>params1: {{ $attrs.params1 }}</p><p>params2: {{ $attrs.params2 }}</p><p>params3: {{ $attrs.params3 }}</p><Groundson v-bind="$attrs" :params4="params4"/></div>
</template><script>
import Groundson from "./Groundson.vue";
export default {name: 'children',components: { Groundson },props: {params1: {type: String,default: ""}},data() {return {params4: '測試4'}},mounted() {console.log("children $attrs:", this.$attrs);},
};
</script>

孫組件:

<!-- 孫組件 -->
<template><div></div>
</template>
<script>export default {name: 'groundson',mounted() {console.log("groundson $attrs:", this.$attrs);},
};
</script>

頁面:

在這里插入圖片描述

打印:

在這里插入圖片描述
總結:

  • 沒有通過 v-bind 傳遞給子組件的,子組件的 $attrs 中不會有該屬性

  • 通過 v-bind 傳遞給了子組件,但是子組件使用了 props 接收的,子組件的 $attrs 中不會有該屬性

  • $attrs 中的屬性值是響應式的

  • 在子組件中使用 v-bind=“$attrs” 可以將子組件的 $attrs 中的所有屬性都傳遞給孫子組件,孫子組件也是按同樣的規則接收

inheritAttrs 的作用:

觀察頁面元素發現:

在這里插入圖片描述
子組件的根元素和孫子組件的根元素都多了一些屬性

官方解釋:默認情況下,父組件傳遞的,但沒有被子組件解析為 props 的 attributes 綁定會被“透傳”。這意味著當我們有一個單根節點的子組件時,這些綁定會被作為一個常規的 HTML attribute 應用在子組件的根節點元素上。我們可以通過設置 inheritAttrs 為 false 來禁用這個默認行為。

例如在子組件中加上 inheritAttrs: false

在這里插入圖片描述
子組件根節點的屬性消失了,由于沒有在孫子組件中設置,孫子組件的根節點還保留著屬性

$listeners

$listeners 包含了父組件傳遞給子組件的所有事件監聽器(即 v-on 綁定的事件)。

與 $attrs 類似, $attrs 是傳遞屬性, $listeners 是傳遞方法。這里就不再舉例了。

注意:在 Vue3 中,$listeners 已經被移除,其功能被合并到了 $attrs 中。

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

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

相關文章

ComfyUI簡介

一、ComfyUI 是什么&#xff1f; ComfyUI 是一款基于節點的圖形用戶界面&#xff08;GUI&#xff09;&#xff0c;專為 Stable Diffusion 設計。它通過模塊化節點連接的方式構建復雜的圖像生成工作流&#xff0c;用戶可自由組合加載模型、輸入提示詞、調整采樣器等操作模塊&am…

我的兩個醫學數據分析技術思路

我的兩個醫學數據分析技術思路 從臨床上獲得的或者公共數據庫數據這種屬于觀察性研究&#xff0c;是對臨床診療過程中自然產生的數據進行分析而獲得疾病發生發展的規律等研究成果。再細分&#xff0c;可以分為獨立危險因素鑒定和預測模型構建兩種。 獨立危險因素鑒定是一直以…

【YOLOv12改進trick】StarBlock引入YOLOv12,創新漲點優化,含創新點Python代碼,方便發論文

??改進模塊??:StarBlock ??解決問題??:采用StarBlock將輸入數據映射到一個極高維的非線性特征空間,生成豐富的特征表示,使得模型在處理復雜數據時更加有效。 ??改進優勢??:簡單粗暴的星型乘法漲點卻很明顯 ??適用場景??:目標檢測、語義分割、自然語言處理…

pyside6學習專欄(九):在PySide6中使用PySide6.QtCharts繪制6種不同的圖表的示例代碼

PySide6的QtCharts類支持繪制各種型狀的圖表&#xff0c;如面積區域圖、餅狀圖、折線圖、直方圖、線條曲線圖、離散點圖等&#xff0c;下面的代碼是采用示例數據繪制這6種圖表的示例代碼,并可實現動畫顯示效果&#xff0c;實際使用時參照代碼中示例數據的格式將實際數據替換即可…

《今日AI-人工智能-編程日報》

1. 字節跳動發布AI編程工具Trae國內版 發布背景&#xff1a;字節跳動于2025年3月3日正式推出國內版AI編程工具Trae&#xff0c;這是國內首個AI原生集成開發環境&#xff08;AI IDE&#xff09;&#xff0c;旨在提升開發者的編程效率與智能化體驗。 核心功能&#xff1a; 搭載d…

doris: MySQL

Doris JDBC Catalog 支持通過標準 JDBC 接口連接 MySQL 數據庫。本文檔介紹如何配置 MySQL 數據庫連接。 使用須知? 要連接到 MySQL 數據庫&#xff0c;您需要 MySQL 5.7, 8.0 或更高版本 MySQL 數據庫的 JDBC 驅動程序&#xff0c;您可以從 Maven 倉庫下載最新或指定版本的…

【LangChain】存儲與管理對話歷史

0. 代碼演示 from langchain_community.chat_message_histories import SQLChatMessageHistorydef get_session_history(session_id):# 通過 session_id 區分對話歷史&#xff0c;并存儲在 sqlite 數據庫中return SQLChatMessageHistory(session_id, "sqlite:///memory.d…

從0開始的操作系統手搓教程21:進程子系統的一個核心功能——簡單的進程切換

目錄 具體說說我們的簡單RR調度 處理時鐘中斷處理函數 調度器 schedule switch_to 我們下面&#xff0c;就要開始真正的進程切換了。在那之前&#xff0c;筆者想要說的是——我們實現的進程切換簡單的無法再簡單了——也就是實現一個超級簡單的輪詢調度器。 每一個進程按照…

mysql新手常見問題解決方法總結

1. 安裝與配置問題 1.1 無法安裝MySQL Server MySQL Server安裝失敗是新手常見的問題之一&#xff0c;以下是具體原因及解決方案&#xff1a; 系統要求不滿足&#xff1a;MySQL對操作系統有最低版本要求&#xff0c;如Windows 7 SP1及以上、macOS 10.13及以上。若系統版本過…

數字組合(信息學奧賽一本通-1291)

【題目描述】 有n個正整數&#xff0c;找出其中和為t(t也是正整數)的可能的組合方式。如&#xff1a;n5,5個數分別為1,2,3,4,5&#xff0c;t5&#xff1b;那么可能的組合有514和523和55三種組合方式。 【輸入】 輸入的第一行是兩個正整數n和t&#xff0c;用空格隔開&#xff0c…

搜索引擎(基于java在線文檔)

背景&#xff1a; 基于java文檔的搜索引擎&#xff0c;可以輸入搜索詞&#xff0c;然后就可以查詢出與搜索詞相關的文檔。該項目的最主要的工作是要構建索引&#xff0c;就是正排和倒排索引。正排索引&#xff1a;根據文檔id獲取到文檔&#xff1b;倒排索引&#xff1a;根據搜…

【每日學點HarmonyOS Next知識】web滾動、事件回調、selectable屬性、監聽H5內部router、Grid嵌套時高度設置

【每日學點HarmonyOS Next知識】web滾動、事件回調、selectable屬性、監聽H5內部router、Grid嵌套時高度設置 1、HarmonyOS WebView加載url無法滾動&#xff1f; scroll 里面嵌套webView&#xff0c;demo參考&#xff1a; // xxx.ets import web_webview from ohos.web.webv…

Flink性能指標詳解MetricsAnalysis

文章目錄 Flink 組成1.JobManager2.TaskManager3.ResourceManager4.Dispatcher5.Client6. Env JobManager MetricsTaskManager Metrics Flink 組成 1.JobManager 管理任務 作業調度&#xff1a;負責接收和調度作業&#xff0c;分配任務到 TaskManager。資源管理&#xff1a;…

Flutter底層實現

1. Dart 語言 Dart 是 Flutter 的主要編程語言。Dart 設計之初就是為了與 JavaScript 兼容&#xff0c;并且可以編譯為機器代碼運行。Dart 提供了一些特性&#xff0c;如異步支持&#xff08;通過 async 和 await&#xff09;&#xff0c;這使得編寫高效的網絡請求和復雜動畫變…

< 自用文兒 > CertBot 申請 SSL 證書 使用 challenge 模式 避開防火墻的阻擋

環境&#xff1a; 騰訊 VPS 騰訊會向你銷售 SSL &#xff0c; 這個本是免費的。CertBot 默認申請證書要用到 80 端口&#xff0c;會蹭邊什么什么條款&#xff0c;備案法律來阻止80端口的通訊&#xff0c;沒有網站也一樣被阻攔。 通過騰訊買的域名&#xff1a; bestherbs.cn …

【AI】【Unity】關于Unity接入DeepseekAPI遇到的坑

前言 由于deepseek網頁端在白天日常抽風&#xff0c;無法正常的使用&#xff0c;所以調用API就成了目前最好的選擇&#xff0c;尤其是Deepseek的API價格低得可怕&#xff0c;這不是和白送的一樣嗎&#xff01;然后使用過很多本地部署接入API的方式&#xff0c;例如Chatbox、Pa…

【微知】Mellanox驅動中to是什么?有哪些超時時間?(time out,心跳2s,reset 1分鐘)

to是tout縮寫&#xff0c;tout是time out 單位是毫秒。 static const u32 tout_def_sw_val[MAX_TIMEOUT_TYPES] {[MLX5_TO_FW_PRE_INIT_TIMEOUT_MS] 120000, # 2min。預初始化的總超時時間[MLX5_TO_FW_PRE_INIT_ON_RECOVERY_TIMEOUT_MS] 7200000, #設備恢復過程中的固件預初…

linux | Vim 命令快捷操作

注&#xff1a;本文為過去的 “vim 使用筆記”。 跳轉命令 跳轉命令 #&#xff1a;向前查找光標當前所在單詞&#xff0c;并跳轉到該單詞的上一個出現位置。*&#xff1a;向后查找光標當前所在單詞&#xff0c;并跳轉到該單詞的下一個出現位置。 行內跳轉 0&#xff1a;跳轉…

樹莓派3B+的初步使用

樹莓派3B的初步使用 一、安裝使用樹莓派系統1.將系統寫入SD卡2.登錄樹莓派系統3.用C和Python編譯運行hello world 一、安裝使用樹莓派系統 1.將系統寫入SD卡 首先&#xff0c;準備至少16GB大小的SD卡以便裝入樹莓派系統&#xff0c;將SD卡插入讀卡器后連接電腦準備給SD卡寫入…

基于Windows11的DockerDesktop安裝和布署方法簡介

基于Windows11的DockerDesktop安裝和布署方法簡介 一、下載安裝Docker docker 下載地址 https://www.docker.com/ Download Docker Desktop 選擇Download for Winodws AMD64下載Docker Desktop Installer.exe 雙點擊 Docker Desktop Installer.exe 進行安裝 測試Docker安裝是…