vue2 八大組件通信,父子通信,跨層級通信,事件總線,vuex等

文章目錄

  • 什么是組件通信?
  • 父子通信流程
  • props
    • Props 定義
    • Props 作用
    • 特點
    • 數組寫法
    • 對象寫法(props校驗)
      • 簡寫只驗證數據類型:
      • 完整寫法,完整的驗證:
  • props父向子傳值
    • 用`props`父傳子
    • 在子組件中修改`props`
  • $emit子向父傳值
    • 用`props`子傳父
    • 用`$emit`子傳父
  • 事件總線
    • 事件總線前置知識
      • `$on`
      • `$off`
    • 事件總線的使用
  • 父通過ref、$refs向子拿值
  • 父子通信`$children` /`$parent`
      • $children
        • 示例
      • $parent
        • 示例
      • 注意事項
  • 跨層級通信`provide/inject`
  • 跨層級通信`attrs/listeners`
  • vuex

什么是組件通信?

組件通信,就是指組件與組件之間的數據傳遞

  • 組件的數據是獨立的,無法直接訪問其他組件的數據
  • 想使用其他組件的數據,就需要組件通信

父子通信流程

  1. 父組件通過 props 將數據傳遞給子組件
  2. 子組件利用 $emit 通知父組件修改更新

在這里插入圖片描述

props

Props 定義

組件上 注冊的一些 自定義屬性

Props 作用

  1. 向子組件傳遞數據

  2. props接受的數據,只讀,不可修改

  3. props接收到的簡單數據類型,不可修改

  4. props接收到的復雜數據類型,可修改,vue也不會報錯,但是不建議這樣做

特點

  1. 可以 傳遞 任意數量 的prop
  2. 可以 傳遞 任意類型 的prop

數組寫法

數組寫法沒有校驗,所以不會在控制臺報錯

props: ['title','text', 'name']

對象寫法(props校驗)

作用:

  • 為組件的 prop 指定驗證要求,不符合要求,控制臺就會有錯誤提示
  • 幫助開發者,快速發現錯誤

簡寫只驗證數據類型:

props: {校驗的屬性名: 數據類型
}

完整寫法,完整的驗證:

props: {校驗的屬性名: {type: 數據類型,  // Number String Boolean ...required: true, // 是否必填default: 默認值, // 默認值(未傳值就使用默認值)validator (value) {  // value接收的就是傳過來的值// 自定義校驗邏輯return 布爾值   // 返回true就代表通過驗證}}
}

示例:

<script>
export default {// 完整寫法(類型、默認值、非空、自定義校驗)props: {w: {type: Number,//required: true,default: 0,validator(val) {// console.log(val)if (val >= 100 || val <= 0) {console.error('傳入的范圍必須是0-100之間')return false} else {return true}},},},
}
</script>

props父向子傳值

props父傳子

  1. 給子組件以添加屬性的方式傳值
  2. 子組件內部通過props接收
  3. 模板中直接使用 props接收的值

在這里插入圖片描述

在子組件中修改props

  1. 如果傳過來的是簡單數據類型,那么是無法修改的
  2. 如果傳過來的是復雜數據類型,那么是可以修改的,但是不建議去修改
  3. 子組件如果要修改父組件傳過來的數據的話,可以用$emit去觸發父組件的自定義事件,讓父組件自己去修改數據

$emit子向父傳值

props子傳父

  1. 父通過自定義屬性將自己的方法傳送出去
  2. 子通過props接受父傳過來的方法
  3. 子通過調用接收過來的方法去傳參的形式傳數據
  4. 因為方法是在父親身上,父親因此接收到了數據

在這里插入圖片描述

$emit子傳父

  1. 給子組件綁定自定義事件,事件觸發時調用來自父親的回調函數
  2. vm.$emit( eventName, […args] )eventName為字符串類型,[…args]可省略,或者傳入多條數據
  3. 在子組件內利用$emit觸發子組件綁定的自定義事件,傳入數據,進行修改更新

在這里插入圖片描述

上圖流程:

  1. 點擊button,調用回調函數changeTitle
  2. 回調函數調用$emit方法
  3. $emit方法會去觸發子組件綁定的自定義事件changeTitle,同時傳入參數
  4. 子組件綁定的自定義事件changeTitle被觸發后會調用回調函數handleChange
  5. 回調函數handleChange用接收到的參數去修改數據msg

事件總線

事件總線前置知識

$on

可以給當前實例添加自定義事件,并且監聽添加的自定義事件

  1. vm.$on( event, callback )
  2. 在 Vue 2 中,$on 是 Vue 實例的一個方法,監聽當前實例上的自定義事件
  3. 事件可以由 vm.$emit 觸發,當觸發這些事件時,可以執行相應的回調函數
  4. 相比于在標簽上直接寫事件,通過$on添加的自定義事件靈活性更強

$off

用于移除自定義事件監聽器

  1. vm.$off( [event, callback] )
  2. 如果沒有提供參數,則移除所有的事件監聽器
  3. 如果只提供了事件,則移除該事件所有的監聽器
  4. 如果同時提供了事件與回調,則只移除這個回調的監聽器

事件總線的使用

事件總線可以用于任意兩個組件之間的通信

1、在src目錄下創建個utils文件夾,里面創建EventBus.js文件(事件總線)

EventBus.js

// 導入vue文件
import Vue from 'vue'
// 創建空vue實例對象
const Bus = new Vue()
// 導出空vue實例對象
export default Bus

2、接收方son1.vue

<template><div>我是son1(接收消息)</div>
</template>
<script>
import Bus from '../utils/EventBus'
export default {name: 'mySon1',created(){Bus.$on('myEvent',(msg)=>{   // 通過$on為Bus自定義事件,當事件觸發時,后面的回調函數接收信息console.log('我是son1拿到了son2的數據:',msg)})}
}
</script>

3、發送方son2.vue

<template><div>我是son2(發布消息)<button @click="sendMsg">發送消息</button></div>
</template>
<script>
import Bus from '@/utils/EventBus'
export default {name: 'mySon2',data() {return {msg: '我是son2中的數據'}},methods: {sendMsg() {Bus.$emit('myEvent', this.msg)  // 通過$emit觸發事件,觸發事件的同時將數據傳出去}}
}
</script>

? Vue 的事件總線通常是通過將其定義在 Vue 的原型上來實現的,這樣任何 Vue 組件都可以通過 this.$bus 來訪問和使用它。這樣做的好處是全局事件總線可以在任何組件內部進行事件的觸發和監聽,提供了一種在組件之間通信的機制

在 Vue 中定義全局事件總線的一般步驟是:

  1. 創建一個新的 Vue 實例作為事件總線。
  2. 將這個 Vue 實例掛載到 Vue 的原型上,通常使用 $bus 作為屬性名。

示例如下:

// main.js 或其他入口文件  
import Vue from 'vue';  
import App from './App.vue';  // 創建一個新的 Vue 實例作為事件總線  
const EventBus = new Vue();  // 將事件總線掛載到 Vue 的原型上  
Vue.prototype.$bus = EventBus;  new Vue({  render: h => h(App),  
}).$mount('#app');

之后,在任何一個 Vue 組件中,你都可以通過 this.$bus 來訪問這個全局事件總線,然后使用 $emit 方法來觸發事件,或者使用 $on$off$once 方法來監聽、取消監聽或一次性監聽事件。

// 在某個組件中觸發事件  
this.$bus.$emit('event-name', payload);  // 在另一個組件中監聽事件  
this.$bus.$on('event-name', (payload) => {  // 處理事件邏輯  
});

雖然全局事件總線提供了一種便捷的組件間通信方式,但它也有一些潛在的問題。過度使用全局事件總線可能導致組件之間的耦合度過高,使得代碼難以理解和維護。因此,在使用全局事件總線時,需要權衡其便利性和潛在的風險,并考慮其他組件間通信的方式,如 props、事件、Vuex 等

父通過ref、$refs向子拿值

? 用ref給子組件打標記,使用$refs獲取到的是vc組件(子組件)實例對象,拿到了vc實例對象了,我們就可以對子組件進行操作,拿取子組件中的值

son.vue

<template><div>我是子組件</div>
</template>
<script>
export default {name: 'mySon',data() {return {msg: '我是子組件中的數據'}}
}
</script>

App.vue

<template><div><son ref="son"></son></div>
</template>
<script>
import son from './components/son.vue';
export default {components: { son },mounted() {console.log(this.$refs.son.msg)    // 我是子組件中的數據}
}
</script>

父子通信$children /$parent

在 Vue 2 中,$children$parent 是兩個實例屬性,它們允許你直接訪問組件的父級或子級組件實例。然而,這種直接的父子通信方式通常不推薦用于復雜的組件結構,因為它們使組件之間的依賴關系變得隱式和難以維護。但是,在某些簡單的場景下,它們可能是有用的。

$children

$children 是一個數組,包含當前組件實例的直接子組件。請注意,$children 并不保證順序,也不是響應式的。

示例
// 父組件
export default {mounted() {console.log(this.$children); // 輸出子組件的數組}
}// 子組件(可能有很多)
// ...

$parent

$parent 屬性用來訪問當前組件實例的父組件實例。

示例
// 子組件
export default {mounted() {console.log(this.$parent); // 輸出父組件的實例// 你可以通過 this.$parent 訪問父組件的數據、方法等}
}

注意事項

  1. 不推薦過度使用:過度依賴 $parent$children 會導致組件之間的耦合度過高,使得代碼難以維護和理解。在復雜的項目中,應該優先使用 props 和 events 進行父子通信,或者使用 Vuex 進行狀態管理。
  2. 非響應式$children 數組不是響應式的,也就是說,當子組件被添加或刪除時,Vue 不會觸發視圖更新。因此,你不應該試圖通過修改 $children 來控制組件的渲染。
  3. 順序不保證$children 數組中的組件順序并不保證與它們在模板中的順序一致。因此,你不應該依賴 $children 數組的順序來訪問特定的子組件。
  4. 循環引用:在某些情況下,可能會出現父子組件之間循環引用的問題。這通常是由于不恰當的組件設計或錯誤的父子關系導致的。在這種情況下,使用 $parent$children 可能會導致不可預測的結果。
  5. 替代方案:對于父子組件之間的通信,推薦使用 props 和 events。對于跨組件通信,可以考慮使用 Vuex 或 EventBus(盡管 EventBus 在大型項目中也可能導致問題)。

跨層級通信provide/inject

provideinject 主要在開發高階插件/組件庫時使用。它們允許一個祖先組件向其所有子孫組件提供一個依賴,不論組件層次有多深,該依賴都可以注入進來。

// 祖先組件  
export default {  provide() {  return {  foo: 'foo'  };  },  // ...  
}  // 子孫組件  
export default {  inject: ['foo'],  created() {  console.log(this.foo); // "foo"  }  // ...  
}

注意:provideinject 主要是為高階插件/組件庫開發而設計的。在大多數應用中,應優先使用 props 和 events 進行父子組件通信,并且對于跨多層級的通信,Vuex 會是更好的選擇

跨層級通信attrs/listeners

在 Vue 2 中,$attrs$listeners 是兩個特殊的屬性,允許你在組件之間透傳(passthrough)屬性和事件監聽器。

  • $attrs 包含了父組件中未被子組件聲明的屬性(attribute)。換句話說,它是一個對象,包含了父組件傳遞給子組件的所有屬性,除了那些在子組件中已經通過 props 選項明確聲明的。

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

這兩個特性在你需要創建封裝組件或高階組件時非常有用,因為它們允許你將額外的屬性和事件監聽器傳遞給子組件,而無需在封裝組件中顯式聲明它們。

下面是一個簡單的例子來說明 $attrs$listeners 的用法:


<!-- ParentComponent.vue -->
<template><div><ChildComponent :prop1="value1" @event1="handleEvent1" class="extra-class" /></div>
</template><script>
import ChildComponent from './ChildComponent.vue';export default {components: {ChildComponent},data() {return {value1: 'someValue'};},methods: {handleEvent1() {console.log('Event 1 triggered');}}
};
</script>
<!-- ChildComponent.vue -->
<template><div><GrandChildComponent v-bind="$attrs" v-on="$listeners" /></div>
</template><script>
import GrandChildComponent from './GrandChildComponent.vue';export default {components: {GrandChildComponent},props: ['prop1'] // 假設 ChildComponent 只聲明了一個 prop1
};
</script>
<!-- GrandChildComponent.vue -->
<template><div><!-- 這里可以訪問通過 $attrs 傳遞過來的 class 和其他未聲明的屬性 --><!-- 也可以觸發通過 $listeners 傳遞過來的事件 --></div>
</template><script>
export default {mounted() {// 假設我們要在這里觸發 event1 事件this.$emit('event1');}
};
</script>

在上面的例子中,ParentComponent 傳遞了一個 prop1 屬性,一個 event1 事件監聽器,以及一個未聲明的 class 屬性給 ChildComponent。在 ChildComponent 中,我們只聲明了 prop1 作為 prop,因此 class 屬性會被包含在 $attrs 中。同時,event1 事件監聽器會被包含在 $listeners 中。

當我們使用 v-bind="$attrs"v-on="$listeners" 將這些屬性和事件監聽器透傳給 GrandChildComponent 時,GrandChildComponent 可以接收到這些屬性和事件,就好像它們是直接被傳遞給它的一樣。這樣,GrandChildComponent 可以訪問 class 屬性和觸發 event1 事件,盡管這些屬性和事件是在 ParentComponent 中定義的。

vuex

Vuex 是一個插件,可以幫我們管理 Vue 通用的數據 (多組件共享的數據)

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

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

相關文章

自定義 Gradle 插件進行統一的靜態代碼分析

靜態代碼分析是一項了不起的技術, 它能讓代碼庫更易于維護. 但是, 如果你在不同的版本庫中擁有多個服務(可能由不同的團隊開發), 如何才能讓每個人都遵循既定的代碼風格呢? 一個好辦法是將所有規則封裝在一個插件中, 該插件會在每個項目構建時自動執行所需的驗證. 因此, 在本…

最新版rancher環境配置安裝和集群搭建詳細教程記錄

&#x1f680; 作者 &#xff1a;“二當家-小D” &#x1f680; 博主簡介&#xff1a;?前荔枝FM架構師、阿里資深工程師||曾任職于阿里巴巴擔任多個項目負責人&#xff0c;8年開發架構經驗&#xff0c;精通java,擅長分布式高并發架構,自動化壓力測試&#xff0c;微服務容器化k…

2024-05-15 問AI: 介紹一下 , Tacotron系列

文心一言 Tacotron系列是由谷歌開發的&#xff0c;主要用于文本到語音&#xff08;TTS&#xff09;轉換的模型。該系列模型基于端到端的序列到序列&#xff08;Seq2Seq&#xff09;架構&#xff0c;能夠直接從文本中生成聽起來自然的語音。 Tacotron模型是首個端到端的TTS深度…

BGP學習三:BGP路由優選12條規則,閃亮登場啦啦啦啦啦

目錄 一.BGP策略工具 &#xff08;1&#xff09;Router-policy作用 &#xff08;2&#xff09;組成部分 &#xff08;3&#xff09;router-policy注意事項 二.優選規則 ①丟棄下一跳不可達 (1)優選prefered-value值大的路由 1.首選優先級 (2)優選local-preference(本地…

Fast-Poisson-Image-Editing代碼介紹(二)

目錄 2.fpei文件下 2.6 number_solver.py 2.7 process.py 2.8 taichi_solver.py 3. 算法總結 4. 代碼運行 4.1 測試 4.2 基于GUI后端自定義框輸出編輯圖像結果 4.2.1 下載open-cv 4.2.2 輸入命令 4.2.3 自定義框 4.2.4 按ESC退出 接續Fast-Poisson-Image-Editing代碼…

企業研發必備網絡:這些關鍵特性,你get了嗎?

對于以研發為核心的企業&#xff0c;如軟件開發、生物制藥、智能汽車等&#xff0c;安全、穩定的研發網絡可是他們業務發展不可或缺的。那么&#xff0c;這些研發網絡究竟有哪些獨特之處&#xff0c;又能為企業帶來哪些價值呢&#xff1f; 首先&#xff0c;我們知道企業研發常常…

開放式耳機哪款具有高性價比?5款高分開放式耳機傾力推薦

作為多年的耳機發燒友&#xff0c;強烈給你們安利開放式耳機&#xff0c;真的是舒適耐用&#xff0c;性價比高。開放式耳機以其獨特的不入耳設計&#xff0c;給用戶帶來了最舒適的佩戴感受。如果小白還不知道怎么選擇高性價比的開放式耳機那就看看我的總結吧&#xff01;下面就…

前端面試題(二十三)(答案版)

面試形式&#xff1a;線上電話面試&#xff1a;一面&#xff1a;時長30分鐘 面試評價&#xff1a;精準考察項目所需技術理論工作實踐 面試官的提問大綱&#xff1a;本公司項目要求本人簡歷 工作經驗&#xff1a;2-4年 公司名稱&#xff1a;深圳XX&#xff08;想知道的就滴喔…

馮喜運:5.15黃金原油晚盤分析:鮑威爾再放鷹,降息懸念重重

【黃金消息面分析】&#xff1a;在全球經濟動蕩和通脹預期不斷上升的背景下&#xff0c;黃金作為傳統的避險資產&#xff0c;再次成為投資者關注的焦點。當前&#xff0c;黃金價格交投于2370美元/盎司左右&#xff0c;連續兩日日線呈現上漲趨勢&#xff0c;而白銀價格也在連續三…

超級數據查看器 教程合集 整理版本 pdf格式 1-31集

點擊下載 超級數據查看器 教程合集整理版本 pdf格式https://download.csdn.net/download/qq63889657/89311725?spm1001.2014.3001.5501

16個可幫助我們工作的職場神器

在職場中&#xff0c;有效的工具可以顯著提高工作效率和組織能力。以下是一些可以幫助我們更好地組織工作的“職場神器”&#xff1a; 項目管理軟件 - zz-plan https://zz-plan.com/ 利用在線甘特圖和看板功能&#xff0c;幫助團隊成員清晰地規劃和跟蹤項目進度。支持資源視圖&…

微信小程序更新日志

還不會用github&#xff0c;git等&#xff0c;先用熟悉的記了 20240514 1.添加了簡易的錄音功能 2.添加了簡易的鬧鐘到時振動功能。 3.準備使用setInterval實現持續振動&#xff0c;直到用戶停止。 4.實現3的功能 5.獲取了訂閱消息模版

如何解決Java 中的精度問題

在 Java 編程中&#xff0c;處理浮點數和超大整數時常常會遇到精度丟失和數值溢出的困擾。為了確保計算結果的精確性&#xff0c;尤其是在金融計算等對精度要求極高的場景中&#xff0c;我們需要使用 BigDecimal 和 BigInteger 類。本文將詳細介紹浮點數精度丟失的原因、如何解…

更新Windows 11 后遇到的一些問題(更新中...)

目錄 插入U盤后讀取不到 在磁盤中新建文件夾需要管理員權限 導致不能安裝一些軟件 插入U盤后讀取不到 解決方法&#xff1a;點擊我的電腦或者是此電腦、選擇管理、找到設備管理器、選擇通用串行總線控制器、右鍵、選擇啟動。 第一步&#xff1a;點擊我的電腦或者是此電腦、選…

數據質量檢測標準

背景 為支持數據倉庫全局的數據質量管控&#xff0c;需做好風險點監控&#xff0c;確保數據的完整性、準確性、及時性、一致性。為此&#xff0c;擬定DQC配置方案&規則&#xff0c;評審通過后落地實施。 目標 核心任務dqc覆蓋率100%&#xff0c;質量問題及時知曉非核心任…

Java學習48-Java 流(Stream)、文件(File)和IO - 復習章節

1.File類的使用 File類的一個實例對應著磁盤上的文件或文件目錄。(必須熟悉)File的實例化(新建一個對象)&#xff0c;常用的方法File類中只有新建&#xff0c;刪除&#xff0c;獲取路徑等方法&#xff0c;不包含讀寫文件的方法&#xff0c;此時需要使用使用下面說的IO流 IO流…

論文閱讀:基于改進 YOLOv5算法的密集動態目標檢測方法

目錄 概要 Motivation 整體架構流程 技術細節 小結 論文地址&#xff1a;基于改進YOLOv5算法的密集動態目標檢測方法 - 中國知網 (cnki.net) 概要 目的&#xff1a;提出一種基于 YOLOv5改進的檢測算法&#xff0c;解決密集動態目標檢測精度低及易漏檢的問題。 方法&…

Linux虛擬主機cPanel重置密碼

我使用的Hostease的Linux虛擬主機產品默認帶普通用戶權限的cPanel面板&#xff0c;這邊自購買后一直未重新設置過cPanel面板的密碼&#xff0c;但是了解到要定期重置一下cPanel面板的密碼&#xff0c;以確保主機數據安全&#xff0c;因此想要進行重置cPanel面板的密碼&#xff…

二刷算法訓練營Day08 | 字符串(1/2)

今日任務&#xff1a; 344.反轉字符串 541. 反轉字符串II卡碼網&#xff1a;54.替換數字 151.翻轉字符串里的單詞卡碼網&#xff1a;55.右旋轉字符串 詳細布置&#xff1a; 1. 344. 反轉字符串 編寫一個函數&#xff0c;其作用是將輸入的字符串反轉過來。輸入字符串以字符數組 …

Django 從零到一:pip 基本使用

文章目錄 pip 常用命令pip 命令演示pip 自動補全 pip 是 Python 的包管理工具&#xff0c;就如同 Gnu/Linux 系統的 yum、apt&#xff0c;MacOS 系統的 brew。因此&#xff0c;我們必須要熟練使用該工具。 接下來我們就演示一下 pip 的常用命令。 pip 常用命令 pip 提供的命令…