Vue 框架組件間通信方式

組件間通信方式


不管是 vue2 還是 vue3,組件通信方式很重要,以下是常見的幾種通信方式:

  • props:可以實現父子組件、子父組件、甚至兄弟組件通信
  • 自定義事件:可以實現子父組件通信
  • 全局事件總線 $bus:可以實現任意組件通信
  • pubsub:發布訂閱模式實現任意組件通信
  • vuex:集中式狀態管理容器,實現任意組件通信
  • ref:父組件獲取子組件實例 VC,獲取子組件的響應式數據以及方法
  • slot:插槽(默認插槽、具名插槽、作用域插槽)實現父子組件通信…

1. props

props 可以實現父子組件通信,在 vue3 中我們可以通過 defineProps 獲取父組件傳遞的數據。且在組件內部不需要引入 defineProps 方法可以直接使用!

父組件給子組件傳遞數據

<Child info="我愛祖國" :money="money"></Child>

子組件獲取父組件傳遞數據:方式1

let props = defineProps({info: {type: String,//接受的數據類型default: '默認參數',//接受默認數據},money: {type: Number,default: 0}
})

子組件獲取父組件傳遞數據:方式2

let props = defineProps(["info",'money']);

子組件獲取到 props 數據就可以在模板中使用了,但是切記 props 是只讀的(只能讀取,不能修改)

2. 自定義事件

在 vue 框架中事件分為兩種:一種是原生的DOM事件,另外一種自定義事件。

原生 DOM 事件可以讓用戶與網頁進行交互,比如 click、dbclick、change、mouseenter、mouseleave、…

自定義事件可以實現子組件給父組件傳遞數據

2.1 原生DOM事件

代碼如下:

 <pre @click="handler">我是祖國的老花骨朵</pre>

當前代碼級給 pre 標簽綁定原生 DOM 事件點擊事件,默認會給事件回調注入 event 事件對象。當然點擊事件想注入多個參數可以按照下圖操作。但是切記注入的事件對象務必叫做 $event.

  <div @click="handler1(1, 2, 3, $event)">我要傳遞多個參數</div>

在 vue3 框架 click、dbclick、change(這類原生DOM事件),不管是在標簽、自定義標簽上(組件標簽)都是原生 DOM 事件。

vue2 中卻不是這樣的,在 vue2 中組件標簽需要通過 native 修飾符才能變為原生 DOM 事件

2.2 自定義事件

自定義事件可以實現子組件給父組件傳遞數據,在項目中是比較常用的。

比如在父組件內部給子組件(Event2)綁定一個自定義事件

<Event2  @xxx="handler3"></Event2>

在 Event2 子組件內部觸發這個自定義事件

<template>
<div><h1>我是子組件2</h1><button @click="handler">點擊我觸發xxx自定義事件</button></div>
</template><script setup lang="ts">let $emit = defineEmits(["xxx"]);const handler = () => {$emit("xxx", "法拉利", "茅臺");};
</script>
<style scoped>
</style>

我們會發現在 script 標簽內部,使用了 defineEmits 方法,此方法是 vue3 提供的方法,不需要引入直接使用。defineEmits 方法執行,傳遞一個數組,數組元素即為將來組件需要觸發的自定義事件類型,此方執行會返回一個 $emit 方法用于觸發自定義事件。

當點擊按鈕的時候,事件回調內部調用 $emit 方法去觸發自定義事件,第一個參數為觸發事件類型,第二個、三個、N個參數即為傳遞給父組件的數據。

需要注意的是:代碼如下

<Event2  @xxx="handler3" @click="handler"></Event2>

正常說組件標簽書寫 @click 應該為原生 DOM 事件,但是如果子組件內部通過 defineEmits 定義就變為自定義事件了

let $emit = defineEmits(["xxx",'click']);

3. 全局事件總線

全局事件總線可以實現任意組件通信,在 vue2 中可以根據 VM 與 VC 關系推出全局事件總線。

但是在 vue3 中沒有 Vue 構造函數,也就沒有 Vue.prototype,以及組合式API寫法沒有 this,那么在 Vue3 想實現全局事件的總線功能就有點不現實啦,如果想在 Vue3 中使用全局事件總線功能,可以使用插件 mitt 實現。

mitt 官網

4. v-model

v-model 指令可是收集表單數據(數據雙向綁定),除此之外它也可以實現父子組件數據同步。

而 v-model 實指利用 props[modelValue] 與自定義事件 [update: modelValue] 實現的。

下方代碼:相當于給組件 Child 傳遞一個 props(modelValue) 與綁定一個自定義事件 update: modelValue

實現父子組件數據同步

<Child v-model="msg"></Child>

在 vue3 中一個組件可以通過使用多個 v-model,讓父子組件多個數據同步,下方代碼相當于給組件 Child 傳遞兩個 props 分別是 pageNo 與 pageSize,以及綁定兩個自定義事件 update: pageNoupdate: pageSize 實現父子數據同步

<Child v-model:pageNo="msg" v-model:pageSize="msg1"></Child>

5. useAttrs

在 Vue3 中可以利用 useAttrs 方法獲取組件的屬性與事件(包含:原生DOM事件或者自定義事件)),次函數功能類似于 Vue2 框架中 $attrs 屬性與 $listeners 方法。

比如:在父組件內部使用一個子組件 my-button

<my-button type="success" size="small" title='標題' @click="handler"></my-button>

子組件內部可以通過 useAttrs 方法獲取組件屬性與事件。因此你也發現了,它類似于 props,可以接受父組件傳遞過來的屬性與屬性值。需要注意如果 defineProps 接受了某一個屬性,useAttrs 方法返回的對象身上就沒有相應屬性與屬性值。

<script setup lang="ts">import {useAttrs} from 'vue';let $attrs = useAttrs();
</script>

6. ref 與 $parent

提及到 ref 可能會想到它可以獲取元素的 DOM 或者獲取子組件實例的 VC。既然可以在父組件內部通過 ref 獲取子組件實例 VC,那么子組件內部的方法與響應式數據父組件可以使用的。

比如:在父組件掛載完畢獲取組件實例

父組件內部代碼:

<template>
<div><h1>ref與$parent</h1><Son ref="son"></Son></div>
</template><script setup lang="ts">import Son from "./Son.vue";import { onMounted, ref } from "vue";const son = ref();onMounted(() => {console.log(son.value);});
</script>

但是需要注意,如果想讓父組件獲取子組件的數據或者方法需要通過 defineExpose 對外暴露,因為 vue3 中組件內部的數據對外“關閉的”,外部不能訪問

<script setup lang="ts">import { ref } from "vue";//數據let money = ref(1000);//方法const handler = ()=>{ }defineExpose({money,handler})
</script>

$parent 可以獲取某一個組件的父組件實例 VC,因此可以使用父組件內部的數據與方法。必須子組件內部擁有一個按鈕點擊時候獲取父組件實例,當然父組件的數據與方法需要通過 defineExpose 方法對外暴露

<button @click="handler($parent)">點擊我獲取父組件實例</button>

7. provide 與 inject

  • provide(提供)
  • inject(注入)

vue3 提供兩個方法 provide 與 inject,可以實現隔輩組件傳遞參數

組件組件提供數據:provide 方法用于提供數據,此方法執需要傳遞兩個參數,分別提供數據的 key 與提供數據 value

<script setup lang="ts">import {provide} from 'vue';provide('token','admin_token');
</script>

后代組件可以通過 inject 方法獲取數據,通過 key 獲取存儲的數值

<script setup lang="ts">import {inject} from 'vue'let token = inject('token');
</script>

8. pinia

pinia也是集中式管理狀態容器,類似于 vuex。但是核心概念沒有mutation、modules,使用方式參照官網

9. slot

插槽:默認插槽、具名插槽、作用域插槽可以實現父子組件通信。

9.1 默認插槽

在子組件內部的模板中書寫slot全局組件標簽

<template>
<div><slot></slot></div>
</template>
<script setup lang="ts">
</script>
<style scoped>
</style>

在父組件內部提供結構:Todo即為子組件,在父組件內部使用的時候,在雙標簽內部書寫結構傳遞給子組件

注意開發項目的時候默認插槽一般只有一個

<Todo><h1>我是默認插槽填充的結構</h1>
</Todo>

9.2 具名插槽

顧名思義,此插槽帶有名字在組件內部留多個指定名字的插槽。

下面是一個子組件內部,模板中留兩個插槽

<template>
<div><h1>todo</h1><slot name="a"></slot><slot name="b"></slot></div>
</template>
<script setup lang="ts">
</script><style scoped>
</style>

父組件內部向指定的具名插槽傳遞結構。需要注意 v-slot:可以替換為 #

<template>
<div><h1>slot</h1><Todo><template v-slot:a>  //可以用#a替換<div>填入組件A部分的結構</div>
</template>
<template v-slot:b>//可以用#b替換
<div>填入組件B部分的結構</div>
</template>
</Todo>
</div>
</template><script setup lang="ts">import Todo from "./Todo.vue";
</script>
<style scoped>
</style>

9.3 作用域插槽

作用域插槽:可以理解為,子組件數據由父組件提供,但是子組件內部決定不了自身結構與外觀(樣式)

子組件 Todo 代碼如下:

<template>
<div><h1>todo</h1><ul><!--組件內部遍歷數組--><li v-for="(item,index) in todos" :key="item.id"><!--作用域插槽將數據回傳給父組件--><slot :$row="item" :$index="index"></slot></li></ul></div>
</template>
<script setup lang="ts">defineProps(['todos']);//接受父組件傳遞過來的數據
</script>
<style scoped>
</style>

父組件內部代碼如下:

<template>
<div><h1>slot</h1><Todo :todos="todos"><template v-slot="{$row,$index}"><!--父組件決定子組件的結構與外觀--><span :style="{color:$row.done?'green':'red'}">{{$row.title}}</span>
</template>
</Todo>
</div>
</template><script setup lang="ts">import Todo from "./Todo.vue";import { ref } from "vue";//父組件內部數據let todos = ref([{ id: 1, title: "吃飯", done: true },{ id: 2, title: "睡覺", done: false },{ id: 3, title: "打豆豆", done: true },]);
</script>
<style scoped>
</style>

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

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

相關文章

SpringBoot學生成績管理系統設計與實現

概述 幽絡源本次分享的基于SpringBoot的學生成績管理系統項目&#xff0c;采用主流的Java技術棧開發&#xff0c;實現了從學生信息管理到成績統計分析的全流程數字化管理。 主要內容 管理員功能模塊 ??學生信息管理??&#xff1a;維護學生基本信息檔案&#xff0c;支持…

青少年編程與數學 02-016 Python數據結構與算法 01課題、算法

青少年編程與數學 02-016 Python數據結構與算法 01課題、算法 一、算法的定義二、算法的設計方法1. 分治法2. 動態規劃法3. 貪心算法4. 回溯法5. 迭代法6. 遞歸法7. 枚舉法8. 分支定界法 三、算法的描述方法1. **自然語言描述**2. **流程圖描述**3. **偽代碼描述**4. **程序設計…

Java 實現冒泡排序:[通俗易懂的排序算法系列之二]

引言 大家好!歡迎來到我的排序算法系列第二篇。今天,我們將學習另一種非常基礎且廣為人知的排序算法——冒泡排序 (Bubble Sort)。 冒泡排序的名字非常形象,它模擬了水中氣泡上升的過程:較小(或較大)的元素會像氣泡一樣,通過不斷交換,逐漸“浮”到數組的一端。 什么是…

struct結構體、union聯合體和枚舉

目錄 一、結構體的聲明和使用 1.1 結構體正常聲明和創建 1.2 結構體特殊聲明 1.3 結構體的自引用 二、結構體內存對齊 2.1 對齊規則 2.2 #pragma修改 三、結構體傳參 四、結構體位段 4.1 位段內存分配 4.2 位段內存應用 五、結構體中的柔性數組概念 六、union聯合…

大模型本地部署系列(2) Ollama部署DeepSeek-R1

成功運行截圖 部署步驟 我們進入到ollama的官網&#xff1a; Ollama?ollama.com/?編輯 找到上方的Models &#xff0c;然后點擊 此時會跳轉到模型列表頁面&#xff1a; 點擊 deepseek-r1 鏈接進去&#xff0c;此時我們會看到下拉框中有各個版本的大模型&#xff0c;越往后…

繪制動態甘特圖(以流水車間調度為例)

import matplotlib.pyplot as plt import matplotlib.animation as animation import numpy as np from matplotlib import cm# 中文字體配置&#xff08;必須放在所有繪圖語句之前&#xff09; plt.rcParams[font.sans-serif] [SimHei] plt.rcParams[axes.unicode_minus] Fa…

PyTorch實現線性回歸的基礎寫法與封裝API寫法

目錄 1. 基礎寫法 1.1導包 2.2加載讀取數據 2.3原始數據可視化(畫圖顯示) 2.4線性回歸的(基礎)分解寫法 2.5定義訓練過程 2.PyTorch實現 線性回歸的封裝寫法(實際項目中的常用寫法) 2.1創建線性回歸模型 2.2定義損失函數 2.3定義優化器 2.4定義訓練過程 1…

python 常用的6個爬蟲第三方庫

Python中有非常多用于網絡數據采集的庫&#xff0c;功能非常強大&#xff0c;有的用于抓取網頁&#xff0c;有的用于解析網頁&#xff0c;這里介紹6個最常用的庫。 1. BeautifulSoup BeautifulSoup是最常用的Python網頁解析庫之一&#xff0c;可將 HTML 和 XML 文檔解析為樹形…

基于BP神經網絡的雜草智能識別系統(雜草識別、Python項目)

基于BP神經網絡的雜草智能識別系統 項目介紹 本項目是一個基于PyQt5和BP神經網絡的雜草智能識別系統。系統通過圖像處理和神經網絡技術&#xff0c; 能夠識別8種不同的雜草類別。用戶可以通過上傳圖片&#xff0c;系統會自動識別圖片中的雜草類別&#xff0c;并顯示識別結果和…

Python3筆記之號稱替代pip的uv包管理器

uv是什么&#xff1f; uv&#xff0c;這是一個由 Astral 團隊開發的極快速的Python包和項目管理工具&#xff0c;用Rust語言編寫。它集成了多種功能&#xff0c;旨在替代pip、pip-tools、pipx、poetry、pyenv、twine、virtualenv等多個工具&#xff0c;提供更高效、更全面的Py…

IT管理思路

甲方CIO和IT管理者-如何做好組織級IT能力提升_嗶哩嗶哩_bilibili

ChatGPT的GPT-4o創建圖像Q版人物提示詞實例展示

最近感覺GPT-4o發布的新功能真的強大&#xff0c;所以總結了一些提示詞分享給大家&#xff0c;大家可以去試試&#xff0c;玩法多多&#xff0c;可以用GPT-4o生成圖片&#xff0c;然后用可靈進行圖生視頻&#xff0c;就能去發布視頻了&#xff01;接下來和筆者一起來試試&#…

Transformer Decoder Block的幾個優化方案

寫在前面 在大型語言模型(LLM)的演進浪潮中,Transformer 架構憑借其強大的并行計算能力和對長距離依賴的出色捕捉,奠定了核心地位。然而,標準的 Transformer Decoder Block 遵循著一種相對固定的模式:先進行自注意力(Self-Attention)捕捉上下文信息,再通過前饋神經網…

五種IO模型與select和poll分別實現多路轉接

五種IO模型與select和poll分別實現多路轉接 何為IO 不論是在前面文件部分&#xff0c;還是后面的網絡部分&#xff0c;IO都是非常常見的。但是當時只是簡單對IO進行提及&#xff0c;并沒有對IO的本質進行介紹。那么到底何為IO&#xff1f;IO全稱為輸入和輸出&#xff0c;而任…

單例模式的寫法(保證線程安全)

1. 引言 1.1 什么是單例模式&#xff1f; 單例模式&#xff08;Singleton Pattern&#xff09;是一種創建型設計模式&#xff0c;它確保一個類只有一個實例&#xff0c;并提供一個全局訪問點。 核心思想&#xff1a;控制實例化過程&#xff0c;避免重復創建對象。 1.2 為什么…

C++ 環境設置

C++ 環境設置 引言 C++作為一種高性能的編程語言,廣泛應用于系統軟件、游戲開發、實時系統等領域。為了能夠順利進行C++編程,我們需要在計算機上配置合適的開發環境。本文將詳細講解如何在Windows、macOS和Linux系統中設置C++開發環境。 Windows系統下C++環境設置 1. 安裝…

【Kafka基礎】ZooKeeper在Kafka中的核心作用:分布式系統中樞神經系統

在分布式系統的世界里&#xff0c;協調和管理多個節點間的狀態是一項復雜而關鍵的任務。Apache Kafka作為一款高性能的分布式消息系統&#xff0c;其設計哲學是"專為單一目的而優化"——即高效處理消息流。為了實現這一目標&#xff0c;Kafka選擇將集群協調管理的重任…

<《AI大模型應知應會100篇》第8篇:大模型的知識獲取方式及其局限性

第8篇&#xff1a;大模型的知識獲取方式及其局限性 摘要 大模型&#xff08;如GPT、BERT、Qwen、DeepSeek等&#xff09;憑借其卓越的自然語言處理能力&#xff0c;已經成為人工智能領域的明星。然而&#xff0c;這些模型“知道”什么&#xff1f;它們如何獲取知識&#xff1f…

ESModule和CommonJS在Node中的區別

ESModule console.log(require);//>errorconsole.log(module);//>errorconsole.log(exports);//>errorconsole.log(__filename);//>errorconsole.log(__dirname);//>error全部報錯commonjs console.log(require);console.log(module);console.log(exports);co…

Spring Boot 配置文件加載優先級全解析

精心整理了最新的面試資料和簡歷模板&#xff0c;有需要的可以自行獲取 點擊前往百度網盤獲取 點擊前往夸克網盤獲取 Spring Boot 配置文件加載優先級全解析 Spring Boot 的配置文件加載機制是開發者管理不同環境配置的核心功能之一。其通過外部化配置&#xff08;Externaliz…