1.props(父組件傳遞給子組件)
1.1 實(shí)現(xiàn)
如果你沒有使用 <script setup>,props 必須以 props 選項(xiàng)的方式聲明,props 對(duì)象會(huì)作為 setup() 函數(shù)的第一個(gè)參數(shù)被傳入:
在子組件中:
export default {
props: {
title: String,
age: Number
? }
setup(props) {
console.log(props.title)
}
}
在父組件中:
<p-child title="james" :age="12"></p-child>
一個(gè)組件可以有任意多的 props,默認(rèn)情況下,所有 prop 都接受任意類型的值。
這種情況下,我們可以使用 v-for 來渲染它們:
<p-child
? ? v-for="item in items"
? ? :key="item.id"
? ? :title="item.title"
/>
使用 v-bind (簡(jiǎn)寫':')來傳遞動(dòng)態(tài) prop 值
1.2 單項(xiàng)數(shù)據(jù)流
所有的 prop 都使得其父子 prop 之間形成了一個(gè)單向下行綁定:父級(jí) prop 的更新會(huì)向下流動(dòng)到子組件中,但是反過來則不行。這樣會(huì)防止從子組件意外變更父級(jí)組件的狀態(tài),從而導(dǎo)致你的應(yīng)用的數(shù)據(jù)流向難以理解。
另外,每次父級(jí)組件發(fā)生變更時(shí),子組件中所有的 prop 都將會(huì)刷新為最新的值。這意味著你不應(yīng)該在一個(gè)子組件內(nèi)部改變 prop。如果你這樣做了,Vue 會(huì)在瀏覽器的控制臺(tái)中發(fā)出警告。
2.emit(子組件傳遞給父組件)
在子組件中,通過 emit() 來觸發(fā)事件,通知父組件處理
在父組件中,監(jiān)聽子組件事件
實(shí)例子組件:
<template>
<div>
<a-button @click="clickHandle">組件傳參</a-button>
</div>
</template>
<script>
export default {
name: 'test',
emits: ['changeMsg'],
setup (props, { emit }) {
function clickHandle () {
emit('changeMsg', '我是子組件值')
}
return {
clickHandle
}
}
};
</script>
父組件:
<template>
<h3>{{description}}</h3>
<HelloWorld @changeMsg="childEvent"></HelloWorld>
</template>
<script lang="ts">
import HelloWorld from '../components/HelloWorld.vue'
import { ref, defineComponent } from 'vue'
export default defineComponent({
name: 'Home',
components: { HelloWorld },
setup() {
const description = ref('Default message')
const childEvent = (msg: string): void => {
description.value = msg
}
return {
description,
childEvent,
}
},
})
</script>
組件實(shí)例提供了一個(gè)自定義事件系統(tǒng)。父組件可以通過 v-on 或 @ 來選擇性地監(jiān)聽子組件上拋的事件,就像監(jiān)聽原生 DOM 事件那樣。
官方文檔實(shí)例
子組件:
子組件可以通過調(diào)用內(nèi)置的 $emit 方法,通過傳入事件名稱來拋出一個(gè)事件:
<template>
<div class="blog-post">
<h4>{{ title }}</h4>
<button @click="$emit('enlarge-text')">Enlarge text</button>
</div>
</template>
父組件:
<BlogPost
...
@enlarge-text="postFontSize += 0.1"
/>
3.雙向綁定v-model
2的例子v-on改為v-model
4.依賴注入
使用Prop有時(shí)會(huì)遇到逐級(jí)透?jìng)鞯膯栴}。如下圖所示:

通常情況下,當(dāng)我們需要從父組件向子組件傳遞數(shù)據(jù)時(shí),會(huì)使用 props。想象一下這樣的結(jié)構(gòu):有一些多層級(jí)嵌套的組件,形成了一顆巨大的組件樹,而某個(gè)深層的子組件需要一個(gè)較遠(yuǎn)的祖先組件中的部分?jǐn)?shù)據(jù)。在這種情況下,如果僅使用 props 則必須將其沿著組件鏈逐級(jí)傳遞下去,這會(huì)非常麻煩。
雖然這里的 <Footer> 組件可能根本不關(guān)心這些 props,但為了使 <DeepChild> 能訪問到它們,仍然需要定義并向下傳遞。如果組件鏈路非常長(zhǎng),可能會(huì)影響到更多這條路上的組件。這一問題被稱為“prop 逐級(jí)透?jìng)鳌保@然是我們希望盡量避免的情況。
provide 和 inject 可以幫助我們解決這一問題。 一個(gè)父組件相對(duì)于其所有的后代組件,會(huì)作為依賴提供者。任何后代的組件樹,無論層級(jí)有多深,都可以注入由父組件提供給整條鏈路的依賴。

4.1 Provide (提供)
要為組件后代提供數(shù)據(jù),需要使用到 provide() 函數(shù):
import { provide } from 'vue'
export default {
setup() {
provide(/* 注入名 */ 'message', /* 值 */ 'hello!')
}
}
provide() 函數(shù)接收兩個(gè)參數(shù)。第一個(gè)參數(shù)被稱為注入名,可以是一個(gè)字符串或是一個(gè) Symbol。后代組件會(huì)用注入名來查找期望注入的值。一個(gè)組件可以多次調(diào)用 provide(),使用不同的注入名,注入不同的依賴值。
第二個(gè)參數(shù)是提供的值,值可以是任意類型,包括響應(yīng)式的狀態(tài),比如一個(gè) ref:
import { ref, provide } from 'vue'
const count = ref(0)
provide('key', count)
提供的響應(yīng)式狀態(tài)使后代組件可以由此和提供者建立響應(yīng)式的聯(lián)系。
4.2 Inject (注入)
要注入上層組件提供的數(shù)據(jù),需使用 inject() 函數(shù):
<!-- 在供給方組件內(nèi) -->
<script setup>
import { provide, ref } from 'vue'
const location = ref('North Pole')
function updateLocation() {
location.value = 'South Pole'
}
provide('location', {
location,
updateLocation
})
</script>
<!-- 在注入方組件 -->
<script setup>
import { inject } from 'vue'
const { location, updateLocation } = inject('location')
</script>
<template>
<button @click="updateLocation">{{ location }}</button>
</template>
注意:provide / inject 類似于消息的訂閱和發(fā)布,遵循 vue 當(dāng)中的單項(xiàng)數(shù)據(jù)流,什么意思呢?就是數(shù)據(jù)在哪,修改只能在哪,不能在數(shù)據(jù)傳遞處修改數(shù)據(jù),容易造成狀態(tài)不可預(yù)測(cè)。
在訂閱組件內(nèi)修改值的時(shí)候,可以被正常修改,如果其他組件也使用該值的時(shí)候,狀態(tài)容易造成混亂,所以需要在源頭上規(guī)避問題。
5.ref 實(shí)現(xiàn)組件的子傳父、父?jìng)髯?/span>
5.1 組件上的 ref
組件上的ref獲得的值是組件實(shí)例:
<child ref="child"></child>
ref被用來給元素或子組件注冊(cè)引用信息。引用信息將會(huì)注冊(cè)在父組件的$refs對(duì)象上
fatherMethod() {this.$refs.child.childMethods();}
通過this.$refs.child找到的是子組件
多個(gè)組件實(shí)例可以結(jié)合${}使用
<div
v-for="item in items"
:key="item.id">
<p-child
:types="item.id"
:ref="`${item.id}Ref`"
></p-child>
</div>
5.2 子組件傳遞給父組件寫法:
子組件:
? export default {
data() {
return {
name: '測(cè)試'
};
},
methods: {
childMethods() {
console.log(this.name);
}
}
};
父組件:
fatherMethod() {this.$refs.child.name}
聲明 ref 并調(diào)用可以獲取子組件 data 中 數(shù)據(jù):
5.3 使用ref實(shí)現(xiàn)父組件傳遞給子組件:
childData: {
title: String,
? ?age: Number
},
init: (Data: any) => {
let data = { ...Data };
childData = {
title: data.title,
age: data.age,
};
子組件定義好需要接受的數(shù)據(jù),并寫好接收方法。文章來源:http://www.zghlxwxcb.cn/news/detail-811355.html
注:vue3 的setup中是沒有辦法直接使用this的寫法:文章來源地址http://www.zghlxwxcb.cn/news/detail-811355.html
const child = ref(null);
(child.value as any).(Data)
到了這里,關(guān)于前端學(xué)習(xí)筆記(14)-Vue3組件傳參的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!