Vue 是一个渐进式的 JavaScript 框架,通过组件化的方式构建应用。在 Vue 中,组件通信指的是不同组件之间传递数据、共享数据或调用方法等行为。在前端开发中,子组件和父组件之间的通信是非常常见和重要的。
父子组件通信的常用方法:
- Props 属性传递:父组件通过 props 将数据或方法传递给子组件,子组件通过 props 接收并使用传递过来的数据或方法。
- Emit 事件触发:子组件通过 $emit 方法触发一个自定义事件,并将数据传递给父组件,父组件通过监听这个事件来接收数据。
父组件向子组件转递信息
父组件通过 props 将数据或方法传递给子组件,子组件通过 props 接收并使用传递过来的数据或方法。
- 父组件:通过属性把数据绑定给子组件
xml
<template>
<div>
<book :data='list.song' />
</div>
</template>
<script setup>
import { reactive } from 'vue'
import book from '../../myAPP/src/components/book.vue'
const list = reactive({
song: {
img: 'https://th.bing.com/th/id/OIP.YtoLm8HlmH3moaSqh41vJQHaHa?w=168&h=180&c=7&r=0&o=5&dpr=1.3&pid=1.7',
title: '战争与和平',
price: '178.5',
num: '001',
}
})
</script>
以这段代码为例:
- 首先父组件要引入子组件
javascript
import book from '../../myAPP/src/components/book.vue'
- 父组件通过绑定属性:date把响应式数据song.list传递给了子组件
ruby
<book :data='list.song'/>
- 子组件:通过 props 接收并使用传递过来的数据或回调函数,props里面写下绑定的属性名。
xml
<template>
<div class="book">
<img :src="data.img" />
<br>
<div class="desc">书名:{{ data.title }} </div>
<div class="flex-box">
<div class="price">价格:{{ data.price }} </div>
<div class="market-price">编号:{{ data.num }}</div>
</div>
</div>
</template>
<script setup>
defineProps({
data: Object
})
</script>
以这段代码为例:
- 在setup语法糖中,defineProps接收了一个对象作为参数,这个对象定义了组件的 props 配置。
xml
<script setup>
defineProps({
data: Object
})
</script>
- 使用父组件传递的数据
xml
<template>
<div class="book">
<img :src="data.img" />
<br>
<div class="desc">书名:{{ data.title }} </div>
<div class="flex-box">
<div class="price">价格:{{ data.price }} </div>
<div class="market-price">编号:{{ data.num }}</div>
</div>
</div>
</template>
- 效果为

子组件向父组件传递信息
子组件通过 $emit 方法触发一个自定义事件,并将数据传递给父组件,父组件通过监听这个事件来接收数据。
- 父组件
xml
<template>
<div>
<book :data="bookInfo" @addbookNum="clog"/>
</div>
</template>
<script setup>
import book from '../../myAPP/src/components/book.vue'
import { reactive } from 'vue'
let bookInfo= reactive({
bookName:'战争与和平',
bookPrice:178.5,
bookAuthor:'列夫·托尔斯泰',
bookNum:0
})
function clog(data) {
bookInfo.bookNum =data
}
</script>
以这段代码为例:
- 引入book.vue组件
javascript
import book from '../../myAPP/src/components/book.vue'
- 引入reactive并生成一个复杂的响应式数据'bookInfo'。
php
import { reactive } from 'vue'
let bookInfo= reactive({
bookName:'战争与和平',
bookPrice:178.5,
bookAuthor:'列夫·托尔斯泰',
bookNum:0
})
- 使用book组件的同时通过绑定属性:date把响应式数据'bookInfo'的值传递给了子组件,并且监听子组件的'addbookNum'事件,当这个事件触发时会执行'clog'这个函数。
ini
<book :data="bookInfo" @addbookNum="clog"/>
- clog函数接收子组件传递的数据,并将值赋给'bookNum'。
ini
function clog(data) {
bookInfo.bookNum =data
}
- 子组件
xml
<template>
<div>
<text>书名:{{ data.bookName }}</text>
<text>作者:{{ data.bookAuthor }}</text>
<text>价格:{{ data.bookPrice }}</text>
<text>数量:{{ data.bookNum }}</text>
<br>
<button @click="addbookNum">图书数量加1</button>
</div>
</template>
<script setup>
import { defineEmits,ref,defineProps } from 'vue';
defineProps({
data:Object
})
const num = ref(0)
const emit = defineEmits(['addbookNum']);
const addbookNum=()=> {
emit('addbookNum', ++num.value)
}
</script>
以这段代码为例:
- 接收父组件传过来的数据。
scss
defineProps({
data: Object
})
- 引入ref,并定义一个初始值为0的响应式数据'num'。
csharp
import { defineEmits,ref,defineProps } from 'vue';
const num = ref(0)
- 通过defineEmits得到emit方法。使用defineEmits函数定义了一个名为'addbookNum'的自定义事件。通过emit方法触发名为'addbookNum'的自定义事件,并将'++num.value'的值作为参数传递给父组件。
ini
const emit = defineEmits(['addbookNum']);
const addbookNum=()=> {
emit('addbookNum', ++num.value)
}
- 当点击按钮时,会执行'addbookNum'函数。
ini
<button @click="addbookNum">图书数量加1</button>
- 初始效果为:

- 点击按钮后:

总结
父子组件通信是vue.js中常用的组件通信方法,在实际的开发中需要根据不同的情况选择合适的通信方法。