跳到主要内容

组件通信

一、attrs 通信


描述: attrs 主要用于子组件获取父组件中没有通过 props 或者 emits 接收的属性和自定义事件。

<template>
<Child :a="a" :b="b" :c="c" @handleChange="handleChange" />
</template>

<script setup>
import { ref, onMounted } from 'vue';
import Child from './components/Child.vue';

const a = ref(0);
const b = ref(1);
const c = ref(2);

const handleChange = value => {
console.log(value);
};
</script>

二、props 通信


描述: 父组件通过 props 传递数据给子组件, 子组件设置 props 属性,定义接收父组件传递过来的数据。

<template>
<Child :count="count" />
</template>

<script setup>
import { ref, watch } from 'vue';
import Child from './components/Child.vue';

const count = ref(0);

watch(count, (newValue, oldValue) => {
console.log(newValue);
});
</script>

三、$emit 通信


描述: 子组件通过 $emit 触发自定义事件, 数据以参数的形式传递给父组件

<template>
<Child :count="count" @handleChangeCount="handleChangeCount" />
</template>

<script setup>
import { ref, watch } from 'vue';
import Child from './components/Child.vue';

const count = ref(0);

const handleChangeCount = value => {
count.value = value;
};

watch(count, (newValue, oldValue) => {
console.log(newValue);
});
</script>

四、EventBus


<template>
<div id="div-app">
<button @click="handleClick">触发</button>
<Child />
</div>

</template>

<script setup>
import { ref } from 'vue';
import eventBus from "./eventBus.js"
import Child from "./components/Child.vue"


const handleClick = ()=>{
eventBus.$emit('v-click',{ a: 1});
}
</script>

五、自定义事件


<template>
<div id="div-app">
<button @click="handleClick">触发自定义事件</button>
<Child />
</div>

</template>

<script setup>
import { ref } from 'vue';
import Child from "./components/Child.vue"
import customEvent from "./customEvent.ts"

const handleClick = ()=>{
const divApp = document.querySelector('#div-app');
customEvent('v-click-div-app',divApp,{ a: 1});
}
</script>

六、expose & ref 组合通信


描述: 在子组件中,通过 expose 或者 defineExpose 向外暴露属性或者方法, 父组件便可以使用 ref 获取到子组件身上暴露的属性或者方法

<template>
<Child ref="child" />
</template>

<script setup>
import { ref, onMounted } from 'vue';
import Child from './components/Child.vue';

const child = ref(null);

onMounted(() => {
console.log('child', child);
console.log('child.count', child.value.count);
});
</script>

七、provide & inject 组合通信


<template>
<div>
{{ a }}

<button @click="changeA(a+1)">父组件按钮</button>
<Child></Child>
</div>
</template>

<script setup lang="ts">
import { provide, reactive, ref } from "vue";
import Child from "./Child.vue"

const a = ref(0);
const changeA = (value: number)=>{
a.value = value;
}

const b = reactive({
a,
changeA,
});

provide('a',a.value);
provide('b',b);
</script>

八、v-model & $emit 组合通信


描述: 父组件通过v-model传递数据,子组件通过$emit('update:字段名',更新后的数据) 更新父组件数据

<template>
<Child v-model:count="count" />
</template>

<script setup>
import { ref, watch } from 'vue';
import Child from './components/Child.vue';

const count = ref(0);

watch(count, (newValue, oldValue) => {
console.log(newValue);
});
</script>

九、parent & root & children 通信