父子通信基本上是最常见使用最频繁的通信方式,可以解决大部分开发中的数据通信问题,简单易操作。此文章包含父组件传递数据给子组件,以及子组件传递数据给父组件这两种通信情况。
父传子
父传子:父组件直接把要传递的数据写在子组件标签身上,子组件通过 defineProps 接收父组件传递过来的数据,之后该数据即可在子组件内部使用。
Parent.vue
<script setup>
import { ref } from 'vue'
import Child from './Child.vue'
const msg = ref('hello world!')
</script>
<template>
<h1>我是父组件</h1>
<pre>我要传递给父组件的数据是:{{ msg }}</pre>
<Child :parentData="msg"></Child>
</template>
Child.vue
<script setup>
defineProps(['parentData'])
</script>
<template>
<hr />
<h2>我是子组件</h2>
<pre>我是父组件传递过来的数据:{{ parentData }}</pre>
</template>
PS:值得注意的是,在书写组件标签时,最好书写成双标签的形式
<Child></Child>,而不是<Child />
子传父
子传父:在父组件中,也就是子组件的标签身上定义自定义事件,该事件的作用就是接收子组件传递过来的值,然后进行一些操作;在子组件中,通过
defineEmits方法,参数是一个数组或者对象,该方法返回一个箭头函数,这个函数需要传递参数,第一个参数是事件类型(事件名称),第二个及以后的参数都表示要传递给父组件的数据。
Parent.vue
<script setup>
import { ref } from 'vue'
import Child from './Child.vue'
const msg = ref()
const customHandler = (val) => {
msg.value = val.value
}
</script>
<template>
<h1>我是父组件</h1>
<pre>这是子组件传递给我的数据:{{ msg }}</pre>
<Child @my-event="customHandler"></Child>
</template>
Child.vue
<script setup>
import { onMounted, ref } from 'vue'
const $emit = defineEmits(['my-event'])
const msg = ref('hello vue!')
onMounted(() => {
$emit('my-event', msg)
})
</script>
<template>
<hr />
<h2>我是子组件</h2>
<pre>这是我要传递给父组件的数据:{{ msg }}</pre>
</template>
稍微修改一下,即可实现子组件点击按钮父组件的值发生改变
Parent.vue
<script setup>
import { ref } from 'vue'
import Child from './Child.vue'
const msg = ref('hello world!')
const customHandler = (val) => {
msg.value = val
}
</script>
<template>
<h1>我是父组件</h1>
<pre>我的数据等会要被子组件改变了:{{ msg }}</pre>
<Child :parentData="msg" @my-event="customHandler"></Child>
</template>
Child.vue
<script setup>
defineProps(['parentData'])
const $emit = defineEmits(['my-event'])
const msg = 'hello vue!'
const handlerClick = () => {
$emit('my-event', msg)
}
</script>
<template>
<hr />
<h2>我是子组件</h2>
<pre>我是父组件传递过来的数据:{{ parentData }}</pre>
<h2>点击下方按钮改变父组件的 hello world! 的值</h2>
<button @click="handlerClick">click me!</button>
</template>
总结
- 涉及到两个方法:
defineProps()defineEmits()