Vue3组件通信的具体用法实例
作者:whhhhhhhhhw
前言:
在组件化开发中,需要将页面抽离成组件的形式,抽离之后就涉及到了组件中数据传递,可分为:父传子(props)、子传父(emits)、祖孙通信(provide和inject)、兄弟通信、全局通讯(pinia)。这次我就以博客的形式复习一下前三种通讯,想了解pinia可点击看我前面写的博客。
1.父传子
首先需要在父组件中的子组件标签中添加自定义属性,将需要传递的值放如自定义属性中,在子组件中通过defineProps这个方法获取父组件传递过来的值。具体方法如下:
father.vue:
<template> <div class="father"> <h2>父组件</h2> <!-- 使用自定义属性传统数据 --> <Child :text="text" :sayHello="sayHello"></Child> </div> </template> <script setup> import { ref } from 'vue'; import Child from './Child.vue'; // state const text = ref('我是父组件中的数据') // function function sayHello() { console.log('hello'); } </script>
Chlid.vue:
<template> <div class="child"> <div>子组件:{{ text }}</div> <div>子内容</div> </div> </template> <script setup> // 接收父组件传递来的数据 const props = defineProps({ text: String, sayHello: Function }) // 判断方法是否传递过来,是则执行方法 if (props.sayHello) { props.sayHello() } </script>
从上可以看出,不只有数据可以传递,方法也是可以传递给子组件的。子组件在接收时,需要给数据标注类型。
2.子传父
1.defineExpose+ref
使用defineExpose+ref的方式将子组件中的数据传递给父组件,首先在子组件中定义数据,使用defineExpose方法将数据暴露出去,在父组件中通过ref来接收。
chlid.vue:
<template> <div class="child"> <div>子组件</div> <div>子内容</div> </div> </template> <script setup> import { ref } from 'vue'; // state const childText = ref('我是子组件中的数据') // function function sayHelloFather() { console.log('hello father'); } // 将子组件中的数据暴露出去 defineExpose({ childText, sayHelloFather }) </script>
father:
<template> <div class="father"> <h2>父组件</h2> <!-- 使用自定义属性传统数据 --> <Child ref="childRef"></Child> </div> </template> <script setup> import { onMounted, ref } from 'vue'; import Child from './Child.vue'; // 接收子组件中传递的数据 const childRef = ref({ childText: String, sayHelloFather: Function }) // 打印数据 onMounted(() => { console.log('childText:', childRef.value?.childText); childRef.value?.sayHelloFather() }) </script>
2.v-model
知道了如何将子组件中的数据如何传递给父组件,那如何在子组件中修改父组件中的数据呢,使用到了v-model + defineEmits的方法,首先在父组件中定义一个数据,在其子组件标签上添加v-model:名称 = '定义的数据名称',在子组件中通过defineProps接收传递过来的数据,然后使用defineEmits通知父组件去修改数据,这边我写了一个小例子,代码如下:
father.vue:
<template> <div class="father"> <h2>父组件</h2> <div>{{ content }}</div> <Child v-model:content="content"></Child> </div> </template> <script setup> import { ref } from 'vue'; import Child from './Child.vue'; const content = ref('content') </script>
chlid.vue:
<template> <div class="child"> <div>子组件</div> <input type="text" :value="prop.content" @input="handleInput"> </div> </template> <script setup> // 接收父组件传递过来的数据 const props = defineProps({ content: String }) const emits = defineEmits(['update:content']) function handleInput(e) { const target = e.target.value // 通知父组件修改数据 emits('update:content', target) } </script>
这里例子的意思是,我修改表单的数据时,父组件中对应的数据也会跟着修改,这里有一点需要注意,在通知父组件修改数据的参数,第一个参数是update:content,需要加上update,content需要跟父组件中的子组件标签上的v-model:content中content对应。
在实际开发中父传子和子传父是使用频率最高的。
3.祖孙通信
当需要进行跨组件通信时可以使用到provide和inject(依赖注入)。
具体使用:在祖先组件中通过provide配置向后代组件提供数据。在后代组件中通过inject配置来声明接收数据。
app.vue:
<template> <div class="app"> <Father></Father> </div> </template> <script setup> import { provide, ref } from 'vue'; import Father from './components/Father.vue'; // state const grandFatherData = ref('我是App.vue中的数据,也就是你爷爷辈') // function function sayHello() { console.log('hello'); } provide('appData', { grandFatherData, sayHello }) </script>
chlid.vue:
<template> <div class="child"> <div>子组件</div> <div>app.vue传来的数据:{{ data.grandFatherData }}</div> </div> </template> <script setup> import { inject, onMounted } from 'vue'; const data = inject('appData') onMounted(()=>{ data.sayHello() }) </script>
这样我们就可以获取到祖先组件传来的数据了
结语:
组件通信是Vue开发中的核心技能,掌握多种通信方式可以灵活应对不同场景的需求。从简单的父子通信到复杂的跨层级通信,合理选择方法能让代码更清晰、维护更方便。
到此这篇关于Vue3组件通信具体用法的文章就介绍到这了,更多相关Vue3组件通信内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!