欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Vue3父子組件間傳參通信的四種方式

 更新時(shí)間:2023年05月09日 11:17:35   作者:不會(huì)寫(xiě)代碼的小周  
近期學(xué)習(xí)vue3的父子組件之間的傳值,發(fā)現(xiàn)跟vue2的并沒(méi)有太大的區(qū)別,下面這篇文章主要給大家介紹了關(guān)于Vue3父子組件間傳參通信的四種方式,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下

前言

本文主要是記錄Vue3在setup語(yǔ)法糖下的父子組件間傳參的四種方式

Vue3+TypeScript

一、父?jìng)髯?defineProps

父組件傳值給子組件主要是由父組件為子組件通過(guò)v-bind綁定數(shù)值,而后傳給子組件;子組件則通過(guò)defineProps接收使用。

如下為父組件Father.vue

<template>
  <div class="fa">
    <div style="margin: 10px;">我是父組件</div>
    <Son :fatherMessage="fatherMessage"></Son>
  </div>
</template>
<script setup lang="ts">
import Son from './Son.vue'
import {ref} from "vue";
const fatherMessage = ref<string>("我是父組件傳過(guò)來(lái)的值")
</script>
<style scoped>
.fa{
  border: 3px solid cornflowerblue;
  width: 400px;
  text-align: center;
}
</style>

如下為子組件Son.vue

<template>
  <div style="margin: 10px;border: 2px solid red">
    我是子組件
    <div style="margin: 5px;border: 2px solid gold">
      父組件傳值接收區(qū):{{fatherMessage}}
    </div>
  </div>
</template>
<script setup lang="ts">
interface Props {
  fatherMessage?: string,
}
defineProps<Props>()
</script>

父組件Father.vue中在調(diào)用Son.vue這個(gè)子組件時(shí),使用v-bind綁定參數(shù)fatherMessage,并傳給Son.vue

子組件Son.vue使用defineProps接收fatherMessage這個(gè)參數(shù),而后就可以正常使用該參數(shù)。

二、子傳父 defineEmits

子組件傳值給父組件主要是子組件通過(guò)defineEmits注冊(cè)一個(gè)自定義事件,而后觸發(fā)emit去調(diào)用該自定義事件,并傳遞參數(shù)給父組件。

在父組件中調(diào)用子組件時(shí),通過(guò)v-on綁定一個(gè)函數(shù),通過(guò)該函數(shù)獲取傳過(guò)來(lái)的值。

如下為子組件Son.vue

<template>
  <div style="margin: 10px;border: 2px solid red">
    我是子組件
    <button @click="transValue" style="margin: 5px">傳值給父組件</button>
  </div>
</template>

<script setup lang="ts">
import {ref} from "vue";

// 定義所要傳給父組件的值
const value = ref<String>("我是子組件傳給父組件的值")

// 使用defineEmits注冊(cè)一個(gè)自定義事件
const emit = defineEmits(["getValue"])

// 點(diǎn)擊事件觸發(fā)emit,去調(diào)用我們注冊(cè)的自定義事件getValue,并傳遞value參數(shù)至父組件
const transValue = () => {
  emit("getValue", value.value)
}

</script>

如下為父組件Father.vue

<template>
  <div class="fa">
    <div style="margin: 10px;">我是父組件</div>
    父組件接收子組件傳的值:{{sonMessage}}
    <Son @getValue="getSonValue"></Son>
  </div>
</template>

<script setup lang="ts">
import Son from './Son.vue'
import {ref} from "vue";

const sonMessage = ref<string>("")
const getSonValue = (value: string) => {
  sonMessage.value = value
}
</script>

<style scoped>
.fa{
  border: 3px solid cornflowerblue;
  width: 400px;
  text-align: center;
}
</style>

父組件Father.vue中在調(diào)用Son.vue這個(gè)子組件時(shí),當(dāng)子組件Son.vue需要傳參給父組件Father.vue時(shí),使用defineEmits注冊(cè)一個(gè)事件getValue,而后設(shè)置點(diǎn)擊事件transValue去觸發(fā)emit,去調(diào)用我們注冊(cè)的自定義事件getValue,并傳遞value參數(shù)至父組件。

父組件Father.vue在獲取子組件Son.vue傳過(guò)來(lái)的值時(shí),通過(guò)在子組件上使用v-on設(shè)置響應(yīng)函數(shù)getValue(該函數(shù)與子組件中的注冊(cè)自定義事件getValue名稱(chēng)需一致),并綁定一個(gè)函數(shù)getSonValue來(lái)獲取傳過(guò)來(lái)的值。

三、子組件暴露屬性給父組件 defineExpose

當(dāng)父組件想直接調(diào)用父組件的屬性或者方法時(shí),子組件可以使用defineExpose暴露自身的屬性或者方法,父組件中使用ref調(diào)用子組件暴露的屬性或方法。

如下為子組件Son.vue

<template>
  <div style="margin: 10px;border: 2px solid red">
    我是子組件

  </div>
</template>

<script setup lang="ts">
import {ref, defineExpose} from "vue";

// 暴露給父組件的值
const toFatherValue = ref<string>("我是要暴露給父組件的值")

// 暴露給父組件的方法
const toFatherMethod = () => {
  console.log("我是要暴露給父組件的方法")
}
// 暴露方法和屬性給父組件
defineExpose({toFatherMethod, toFatherValue})

</script>

如下為父組件Father.vue

<template>
  <div class="fa">
    <div style="margin: 10px;">我是父組件</div>
    <button @click="getSonMethod">獲取子組件的方法</button>
    <Son ref="sonMethodRef"></Son>
  </div>
</template>

<script setup lang="ts">
import Son from './Son.vue'
import {ref} from "vue";

const sonMethodRef = ref()

const getSonMethod = () => {
  sonMethodRef.value.toFatherMethod()
  console.log(sonMethodRef.value.toFatherValue)
}

</script>

<style scoped>
.fa{
  border: 3px solid cornflowerblue;
  width: 400px;
  text-align: center;
}
</style>

在子組件中定義屬性toFatherValue和方法toFatherMethod,而后通過(guò)defineExpose暴露出來(lái)。
父組件調(diào)用時(shí),為子組件綁定一個(gè)ref,并定義一個(gè)ref變量sonMethodRef,通過(guò)調(diào)用sonMethodRef,來(lái)獲取子組件暴露出來(lái)的屬性和方法。

四、依賴(lài)注入Provide / Inject

從上面的介紹里我們可以了解到父子組件之間的通信,但是卻存在這樣的情況:有一些多層級(jí)嵌套的組件,形成了一顆巨大的組件樹(shù),而某個(gè)深層的子組件需要一個(gè)較遠(yuǎn)的祖先組件中的部分?jǐn)?shù)據(jù)。在這種情況下,如果僅使用 props 則必須將其沿著組件鏈逐級(jí)傳遞下去,這會(huì)非常麻煩:

雖然這里的 Footer 組件可能根本不關(guān)心這些 props,但為了使 DeepChild 能訪(fǎng)問(wèn)到它們,仍然需要定義并向下傳遞。如果組件鏈路非常長(zhǎng),可能會(huì)影響到更多這條路上的組件。這一問(wèn)題被稱(chēng)為“prop 逐級(jí)透?jìng)?rdquo;,顯然是我們希望盡量避免的情況。
provideinject 可以幫助我們解決這一問(wèn)題。 一個(gè)父組件相對(duì)于其所有的后代組件,會(huì)作為依賴(lài)提供者。任何后代的組件樹(shù),無(wú)論層級(jí)有多深,都可以注入由父組件提供給整條鏈路的依賴(lài)。

如下為父組件Root.vue

<template>
  <div>
    我是root組件
    <Footer></Footer>
  </div>
</template>
<script setup lang="ts">
import { provide, ref } from 'vue'
import Footer from './Footer.vue'
const toChildValue= ref<string>("我是給所有子組件的值")
// 將toChildValue注入到所有子組件中
provide(/* 注入名 */ 'toChildValue', /* 值 */ toChildValue)
</script>

如下為子組件Footer.vue

<template>
  <div>
    我是footer組件
    <div>
      接收父組件的值:{{getFatherValue}}
    </div>
    <DeepChild></DeepChild>
  </div>
</template>
<script setup lang="ts">
import DeepChild from "./DeepChild.vue"
import {ref,inject,Ref} from "vue";
// 獲取父組件提供的值
// 如果沒(méi)有祖先組件提供 "toChildValue"
// ref("") 會(huì)是 "這是默認(rèn)值"
const getFatherValue = inject<Ref<string>>(/* 注入名 */"toChildValue",/* 默認(rèn)值 */ ref(""))
</script>

如下為孫子組件DeepChild.vue

<template>
  <div>
    我是deepChild組件
    <div>
      接收爺爺組件的值:{{getGrandFatherValue}}
    </div>
  </div>
</template>
<script setup lang="ts">
import {inject, ref, Ref} from "vue";
// 獲取爺爺組件提供的值
// 如果沒(méi)有爺爺組件提供 "toChildValue"
// value 會(huì)是 ""
const getGrandFatherValue = inject<Ref<string>>(/* 注入名 */"toChildValue",/* 默認(rèn)值 */ ref(""))
</script>

當(dāng)最頂層的組件Root.vue傳值給所有子組件時(shí),使用provide進(jìn)行注入

provide(/* 注入名 */ 'toChildValue', /* 值 */ toChildValue)

而后無(wú)論哪個(gè)子組件想要獲取toChildValue的值,只需使用inject即可

inject<Ref<string>>(/* 注入名 */"toChildValue",/* 默認(rèn)值 */ ref(""))

當(dāng)提供 / 注入響應(yīng)式的數(shù)據(jù)時(shí),如果想改變數(shù)據(jù)時(shí),建議盡可能將任何對(duì)響應(yīng)式狀態(tài)的變更都保持在供給方組件中,即根組件Root.vue。這樣可以確保所提供狀態(tài)的聲明和變更操作都內(nèi)聚在同一個(gè)組件內(nèi),使其更容易維護(hù)。

有的時(shí)候,我們可能需要在注入方組件中更改數(shù)據(jù)。在這種情況下,我們推薦在供給方組件內(nèi)聲明并提供一個(gè)更改數(shù)據(jù)的方法函數(shù):

如下為父組件Root.vue

<template>
  <div>
    我是root組件
    <Footer></Footer>
  </div>
</template>

<script setup lang="ts">
import {InjectionKey, provide, Ref, ref} from 'vue'
import Footer from './Footer.vue'

const toChildValue= ref<string>("我是給所有子組件的值")
/**
 * 修改父組件值的方法
 */
const changeValue = () => {
  toChildValue.value = "我是父組件修改的值"
}
// 定義一個(gè)注入key的類(lèi)型(建議將注入 key 的類(lèi)型放在一個(gè)單獨(dú)的文件中,這樣它就可以被多個(gè)組件導(dǎo)入)
interface ProvideType {
  toChildValue: Ref<string>;
  changeValue: () => void;
}
// 為注入值標(biāo)記類(lèi)型
const toValue = Symbol() as InjectionKey<ProvideType>
// 將toChildValue和changeValue注入到所有子組件中
provide(/* 注入名 */ 'toValue', /* 值 */{
  toChildValue,
  changeValue
})
</script>

provideinject 通常會(huì)在不同的組件中運(yùn)行。要正確地為注入的值標(biāo)記類(lèi)型,Vue 提供了一個(gè) InjectionKey 接口,它是一個(gè)繼承自 Symbol 的泛型類(lèi)型,可以用來(lái)在提供者和消費(fèi)者之間同步注入值的類(lèi)型。

建議將注入 key 的類(lèi)型放在一個(gè)單獨(dú)的文件中,這樣它就可以被多個(gè)組件導(dǎo)入。

// 定義一個(gè)注入key的類(lèi)型
//(建議將注入 key 的類(lèi)型放在一個(gè)單獨(dú)的文件中,這樣它就可以被多個(gè)組件導(dǎo)入)
interface ProvideType {
  toChildValue: Ref<string>;
  changeValue: () => void;
}
// 為注入值標(biāo)記類(lèi)型
const toValue = Symbol() as InjectionKey<ProvideType>

如下為孫子組件DeepChild.vue

<template>
  <div>
    我是deepChild組件
    <div>
      <button @click="changeValue">改變祖先組件的值</button>
      {{toChildValue}}
    </div>
  </div>
</template>

<script setup lang="ts">
import {inject, ref, Ref} from "vue";

// 定義注入值的類(lèi)型
interface ProvideType {
  toChildValue: Ref<string>;
  changeValue: () => void;
}
// 解構(gòu)獲取父組件傳的值,需要進(jìn)行強(qiáng)制類(lèi)型轉(zhuǎn)換
const {toChildValue, changeValue} = inject(/* 注入名 */"toValue") as ProvideType
// 不解構(gòu)時(shí),只需指定類(lèi)型即可
// const value = inject<ProvideType>(/* 注入名 */"toValue")
</script>

當(dāng)祖先組件提供參數(shù)與方法時(shí),子組件在解構(gòu)時(shí)需要強(qiáng)制轉(zhuǎn)換該值的類(lèi)型

// 解構(gòu)獲取父組件傳的值
const {toChildValue, changeValue} = inject(/* 注入名 */"toValue") as ProvideType

如果子組件在使用時(shí)不進(jìn)行解構(gòu),則直接指明類(lèi)型即可

// 不解構(gòu)時(shí),直接指定類(lèi)型即可
const value = inject<ProvideType>(/* 注入名 */"toValue")

參考

1、小滿(mǎn)ZS 學(xué)習(xí)Vue3 第二十三章(依賴(lài)注入Provide / Inject) 

2、Vue3官網(wǎng) 依賴(lài)注入

總結(jié)

到此這篇關(guān)于Vue3父子組件間傳參通信的四種方式的文章就介紹到這了,更多相關(guān)Vue3父子組件間傳參通信內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Vue組件設(shè)計(jì)-Sticky布局效果示例

    Vue組件設(shè)計(jì)-Sticky布局效果示例

    這篇文章主要介紹了Vue組件設(shè)計(jì)-Sticky布局,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-05-05
  • mint-ui 時(shí)間插件使用及獲取選擇值的方法

    mint-ui 時(shí)間插件使用及獲取選擇值的方法

    下面小編就為大家分享一篇mint-ui 時(shí)間插件使用及獲取選擇值的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-02-02
  • vue?懸浮窗且?guī)ё詣?dòng)吸附功能實(shí)現(xiàn)demo

    vue?懸浮窗且?guī)ё詣?dòng)吸附功能實(shí)現(xiàn)demo

    這篇文章主要為大家介紹了vue?懸浮窗且?guī)ё詣?dòng)吸附功能實(shí)現(xiàn)demo,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-06-06
  • vue如何獲取自定義元素屬性參數(shù)值的方法

    vue如何獲取自定義元素屬性參數(shù)值的方法

    這篇文章主要介紹了vue如何獲取自定義元素屬性參數(shù)值的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05
  • Vue登錄功能實(shí)現(xiàn)全套詳解(含封裝axios)

    Vue登錄功能實(shí)現(xiàn)全套詳解(含封裝axios)

    登錄功能對(duì)于前端剛?cè)腴T(mén)不久的同學(xué)來(lái)說(shuō)較為困難,下面這篇文章主要給大家介紹了關(guān)于Vue登錄功能實(shí)現(xiàn)(含封裝axios)的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-12-12
  • Vue Object 的變化偵測(cè)實(shí)現(xiàn)代碼

    Vue Object 的變化偵測(cè)實(shí)現(xiàn)代碼

    這篇文章主要介紹了Vue Object的變化偵測(cè)實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-04-04
  • vue計(jì)算屬性及函數(shù)的選擇

    vue計(jì)算屬性及函數(shù)的選擇

    這篇文章主要介紹了vue計(jì)算屬性及函數(shù)的選擇,文章圍繞主題的相關(guān)資料展開(kāi)詳細(xì)介紹,需要的小伙伴可以參考一下
    2022-05-05
  • vue2使用ts?vue-class-component的過(guò)程

    vue2使用ts?vue-class-component的過(guò)程

    vue-property-decorator?是一個(gè)?Vue.js?的裝飾器庫(kù),它提供了一些裝飾器來(lái)讓你在?Vue?組件中定義屬性、計(jì)算屬性、方法、事件等,本文給大家介紹vue2使用ts?vue-class-component的相關(guān)知識(shí),感興趣的朋友一起看看吧
    2023-11-11
  • vue.js 嵌套循環(huán)、if判斷、動(dòng)態(tài)刪除的實(shí)例

    vue.js 嵌套循環(huán)、if判斷、動(dòng)態(tài)刪除的實(shí)例

    下面小編就為大家分享一篇vue.js 嵌套循環(huán)、if判斷、動(dòng)態(tài)刪除的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-03-03
  • Vue使用extend動(dòng)態(tài)創(chuàng)建組件的實(shí)現(xiàn)

    Vue使用extend動(dòng)態(tài)創(chuàng)建組件的實(shí)現(xiàn)

    本文主要介紹了Vue使用extend動(dòng)態(tài)創(chuàng)建組件的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04

最新評(píng)論