1. 組件的通信
1.1. 父子組件之間的通信
1.1.1 父組件向子組件傳值
方式一:父組件給子組件傳值時(shí),通過v-on
綁定屬性實(shí)現(xiàn)
// parent.vue
<template>
<div>
父子組件傳值
<children :msg="msg" :foo="foo"/>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import children from './components/children.vue';
let msg = ref('hello word');
let foo = ref(10);
</script>
<style scoped>
</style>
子組件通過defineProps
來接收接收父組件傳遞的值。
- 使用字符串的形式接收父組件傳遞的值
// children.vue
<template>
<div class="wrapper">
這是子組件<br/>
父?jìng)髯樱簕{ props.msg }} {{ props.foo }}
</div>
</template>
<script setup lang="ts">
let props = defineProps(['msg', 'foo'])
</script>
<style scoped>
</style>
- 使用對(duì)象的形式接收父組件傳遞的值
// children.vue
<template>
<div class="wrapper">
這是子組件<br/>
父?jìng)髯樱簕{ props.msg }} {{ props.foo }}
</div>
</template>
<script setup lang="ts">
let props = defineProps({
msg: String,
foo: Number
})
</script>
<style scoped>
</style>
- 使用對(duì)象的形式接收父組件傳遞的值(含默認(rèn)值及必填參數(shù)設(shè)置)
// children.vue
<template>
<div class="wrapper">
這是子組件<br/>
父?jìng)髯樱簕{ props.msg }} {{ props.foo }}
</div>
</template>
<script setup lang="ts">
let props = defineProps({
msg: {
type: String,
default: '',
required: true // 設(shè)置后參數(shù)必傳
},
foo: {
type: Number,
default: 0
}
})
</script>
<style scoped>
</style>
- 結(jié)合 TypeScript 使用
// children.vue
<template>
<div class="wrapper">
這是子組件<br/>
父?jìng)髯樱簕{ props.msg }} {{ props.foo }}
</div>
</template>
<script setup lang="ts">
let props = defineProps<{
msg?: string;
foo: number
}>()
</script>
<style scoped>
</style>
方式二:父組件通過插槽(slot)
向子組件傳遞參數(shù)
- 子組件中通過
slot
標(biāo)簽傳遞參數(shù) - 父組件中通過
template
插入內(nèi)容,通過v-slot
可以接收插槽傳遞的數(shù)據(jù)
<!-- Parent.vue -->
<template>
<Child>
<template #default="{ message }">
{{ message }}
</template>
</Child>
</template>
<script>
import Child from './Child.vue'
</script>
<!-- Child.vue -->
<template>
<div>
<slot :message="message"></slot>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const message = ref('Hello, world!')
</script>
需要注意的是,插槽只能用于傳遞靜態(tài)內(nèi)容,如果需要傳遞動(dòng)態(tài)內(nèi)容,則需要使用props或者provide/inject來實(shí)現(xiàn)。此外,插槽還可以定義多個(gè),并且可以通過name屬性來區(qū)分不同的插槽。
方式三:v-model
,子組件可直接修改父組件傳遞過來的值
在Vue3中,可以使用v-model
指令來實(shí)現(xiàn)子組件直接修改父組件傳遞過來的值。具體來說,可以在父組件中使用v-model
指令將一個(gè)變量與子組件的一個(gè)prop
綁定起來,然后在子組件中使用emit
方法觸發(fā)一個(gè)名為update:
加上prop名字的事件,并傳遞一個(gè)新的值作為參數(shù)。例如:
<!-- VmodelParent.vue -->
<template>
<div>
v-model傳參:父組件
<VmodelChild v-model:isShow="isShow" />
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import VmodelChild from './components/VmodelChild.vue';
const isShow = ref(false)
</script>
<style scoped>
</style>
<!-- VmodelChild.vue -->
<template>
<div>
v-model傳參:子組件
<button @click="handleClick">點(diǎn)擊修改參數(shù)</button>
<br />
{{ props.isShow }}
</div>
</template>
<script setup lang="ts">
import { defineProps, defineEmits } from 'vue';
const props = defineProps({
isShow: {
type: Boolean,
default: false
}
})
const emit = defineEmits(["update:isShow"])
const handleClick = () => {
emit("update:isShow", !props.isShow)
}
</script>
<style scoped>
</style>
1.1.2. 子組件向父組件傳值
子組件向父組件傳值,通過defineEmits
實(shí)現(xiàn)
<template>
<div class="wrapper">
這是子組件<br/>
<button @click="emitToParent">click</button>
</div>
</template>
<script setup lang="ts">
let emit = defineEmits(['event-to-parent'])
let emitToParent = () => {
emit('event-to-parent', '子組件傳遞給父組件的值')
}
</script>
<style scoped>
</style>
1.2. 兄弟組件之間的通信
Vue 3 中移除了 eventBus,但可以借助第三方工具來完成。Vue 官方推薦使用mitt
或 tiny-emitter
。
例子:以mitt
為例
1.2.1. 安裝
yarn add mitt -S
1.2.2. 注冊(cè)
- eventBus.ts
// eventBus.ts
import mitt from 'mitt'
const mitter = mitt();
export default mitter
1.2.3. 使用
- EventBus.vue
// EventBus.vue
<template>
<div>
Event Bus實(shí)現(xiàn)兄弟組件傳參
<EventBusA />
<EventBusB />
</div>
</template>
<script setup lang="ts">
import EventBusA from './components/EventBusA.vue';
import EventBusB from './components/EventBusB.vue';
</script>
<style scoped>
</style>
- EventBusA.vue
// EventBusA.vue
<template>
<div class="wrapper">
兄弟組件A
<button type="button" @click="handleClick">點(diǎn)擊傳參</button>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import mitter from '@/utils/eventBus'
const msg = ref('Hello, world!')
const handleClick = () => {
mitter.emit('msg', msg.value)
}
</script>
<style scoped>
</style>
- EventBusB.vue
// EventBusB.vue
<template>
<div class="wrapper">
兄弟組件B
{{ res }}
</div>
</template>
<script setup lang="ts">
import mitter from '@/utils/eventBus'
import { ref } from 'vue'
const res = ref()
mitter.on('msg', (data) => {
res.value = data
})
</script>
<style scoped>
</style>
1.3. 跨級(jí)組件之間的通信
provide/inject來實(shí)現(xiàn)跨級(jí)組件之間的通信
1.3.1 provide/inject
- parent.vue
// parent.vue
<template>
<div class="wrapper">
兄弟組件傳參,這是父組件
<brotherA />
<brotherB />
</div>
</template>
<script setup lang="ts">
import brotherA from './components/brotherA.vue'
import brotherB from './components/brotherB.vue'
import { provide, ref } from 'vue';
let msg = ref('給孫組件傳遞的值');
provide('msg', msg)
</script>
<style scoped>
</style>
- brotherA.vue
// brotherA.vue
<template>
<div class="wrapper">
子組件A
<grandson />
</div>
</template>
<script setup lang="ts">
import grandson from "./grandson.vue";
import { ref } from 'vue';
</script>
<style scoped>
</style>
- brotherB.vue
// brotherB.vue
<template>
<div class="wrapper">
子組件B
{{ msg }}
</div>
</template>
<script setup lang="ts">
import { inject } from 'vue'
let msg = inject('msg')
</script>
<style scoped>
</style>
- grandson.vue
// grandson.vue
<template>
<div class="wrapper">
這是孫組件
{{ msg }}
</div>
</template>
<script setup lang="ts">
import { inject } from 'vue'
let msg = inject('msg')
</script>
<style scoped>
</style>
1.4. 非父子組件之間的通信
1.4.1. Vuex/Pinia
Vuex 和 Pinia 是 Vue 3 中的狀態(tài)管理工具,使用這兩個(gè)工具可以輕松實(shí)現(xiàn)組件通信。由于這兩個(gè)工具都比較強(qiáng)大,后面會(huì)寫文章詳細(xì)講解。文章來源:http://www.zghlxwxcb.cn/news/detail-425906.html
總結(jié)
組件通信是 Vue 中非常重要的一個(gè)概念,它指的是組件之間傳遞數(shù)據(jù)和事件的過程。在 Vue 中,組件通信主要分為父子組件之間的通信和兄弟組件之間的通信兩種情況。
在父子組件之間的通信中,父組件可以通過v-bind
來向子組件傳遞數(shù)據(jù),而子組件則可以通過defineProps
來接收父組件傳遞的數(shù)據(jù)。同時(shí),子組件也可以通過emit
觸發(fā)自定義事件來向父組件傳遞數(shù)據(jù)。
在兄弟組件之間的通信中,可以通過一個(gè)共同的父組件來實(shí)現(xiàn)數(shù)據(jù)的傳遞和事件的觸發(fā),也可以通過 Vuex 等狀態(tài)管理工具來實(shí)現(xiàn)數(shù)據(jù)的共享。
總之,在組件通信的過程中,需要合理地選擇合適的方法來實(shí)現(xiàn)數(shù)據(jù)和事件的傳遞,以實(shí)現(xiàn)組件之間的良好協(xié)作和高效交互。文章來源地址http://www.zghlxwxcb.cn/news/detail-425906.html
到了這里,關(guān)于Vue 3 第十一章:組件二(組件通信)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!