前言
📢最近准备春招啦了,所以整理了一些前端高频大厂面试题,分享给大家,如有问题欢迎留言指正,面试专栏我会长期更新,欢迎大家点赞🤞、收藏📌,关注➕,感谢!
Vue 组件通信是指在 Vue.js 应用程序中,不同的组件之间进行数据传递和交互的过程。Vue 提供了多种方式来实现组件通信,包括父子组件通信、兄弟组件通信和跨级组件通信等。
父子组件通信
- 父组件通过 props 向子组件传递数据。
- 子组件通过 $emit 触发事件,将数据发送给父组件。
- 子父通信 子组件拿到父组件的数据并修改后emit出来,父组件靠v-model实现双向绑定
- 子父通信 子组件defineExpose暴露出来值,父组件利用ref读取着整个子组件对象来获取值
- 父子通信 父组件 provied 子组件 inject
- EventBus mitt插件,也就是事件总线来传值
父组件通过 props 向子组件传递数据。
xml
<template>
<!-- parent -->
<div class="hd">
<input type="text" name="" id="" v-model="msg">
<button @click="add">添加</button>
</div>
<!-- child -->
<Child :message="message"/>
</template>
<script setup>
import { ref } from 'vue';
import Child from './components/Child_1.vue'
const msg = ref('')
const message = ref('')
const add = () => {
message.value = msg.value
}
</script>
通过引入子组件,在子组件标签中通过动态绑定数据源message
,在点击事件获取表单输入的值,在加入message
数据源中
xml
<!-- child -->
<template>
<div class="bd">
<ul>
<li v-for="item in list">{{item}}</li>
</ul>
</div>
</template>
<script setup>
import { ref } from 'vue';
const list = ref(['html', 'css'])
defineProps({
message: String,
default: ''
})
</script>
子组件通过difineProps
为一个对象,message
为String,default
这个是设置默认值的,然后可以渲染到子组件当中去
子组件 emit发布一个事件,父组件订阅该事件
xml
<!-- parent -->
<template>
<Child @add="handle"/>
<div class="bd">
<ul>
<li v-for="item in list">{{item}}</li>
</ul>
</div>
</template>
<script setup>
import { ref } from 'vue';
import Child from './components/Child_2.vue'
const list = ref(['html', 'css'])
const handle = (e) => {
console.log(e);
list.value.push(e)
}
</script>
自定义事件,通常用来进行 子 -> 父 之间的事件传递,自定义一个add事件,当add事件触发时,handle的事件就自动触发
xml
<!-- child -->
<template>
<div class="hd">
<input type="text" name="" id="" v-model="msg">
<button @click="add">添加</button>
</div>
</template>
<script setup>
import { ref } from 'vue';
const msg = ref('')
const emits = defineEmits(['add']) // 创建一个add事件
const add = () => {
emits('add', msg.value); // 发布add事件
}
</script>
<style lang="css" scoped>
</style>
子父传值这个是重点const emits = defineEmits(['add']) 创建一个事件, emits('add', msg.value); 发布add事件
双向绑定
在子组件标签上绑定属性和自定义事件,子组件内部使用 defineProps
和 defineEmits
接收属性和自定义事件,且子组件内部使用接收的自定义事件修改接收到的属性值,然后父组件根据绑定的自定义事件接收到子组件传递过来的新数据,从而实现父子组件数据同步。
xml
<!-- parent -->
<template>
<Child v-model:list="list"/>
<div class="bd">
<ul>
<li v-for="item in list">{{item}}</li>
</ul>
</div>
</template>
<script setup>
import { ref } from 'vue';
import Child from './components/Child_3.vue'
const list = ref(['html', 'css'])
</script>
xml
<template>
<div class="hd">
<input type="text" name="" id="" v-model="msg">
<button @click="add">添加</button>
</div>
</template>
<script setup>
import { ref } from 'vue';
const msg = ref('')
const props = defineProps({
list: {
type: Array,
default: () => []
}
})
const emits = defineEmits(['update:list'])
const add = () => {
// props.list.push(msg.value) // xxxxxx
const arr = props.list
arr.push(msg.value)
emits('update:list', arr)
}
</script>
子组件defineExpose暴露出来值,父组件利用ref读取着整个子组件对象来获取值
xml
<!-- parent -->
<template>
<Child ref="childRef"/>
<div class="bd">
<ul>
<li v-for="item in childRef?.list">{{item}}</li>
</ul>
</div>
</template>
<script setup>
import { ref } from 'vue';
import Child from './components/Child_4.vue'
const childRef = ref(null)
</script>
获取子组件的dom结构 <Child ref="childRef"/>
来获取list的值
xml
<template>
<div class="hd">
<input type="text" name="" id="" v-model="msg">
<button @click="add">添加</button>
</div>
</template>
<script setup>
import { ref } from 'vue';
const msg = ref('')
const list = ref(['html', 'css'])
const add = () => {
list.value.push(msg.value)
}
defineExpose({ list }) // 愿意暴露出来的变量
</script>
通过defineExpose来暴露出list值,来给父组件来应用
父组件 provied 子组件 inject
xml
<template>
<div class="hd">
<input type="text" name="" id="" v-model="msg">
<button @click="add">添加</button>
</div>
<Child/>
</template>
<script setup>
import { ref, provide } from 'vue';
import Child from './components/Child_5.vue'
const msg = ref('')
const list = ref(['html', 'css'])
provide('list', list.value)
const add = () => {
list.value.push(msg.value)
}
</script>
<style lang="css" scoped>
</style>
通过provide来提供数据,但是这个子组件 或者孙子组件都可以来接收,但是这种不建议用这个,因为这个值在别的地方改变了,这个全部组件都跟着改变
xml
<template>
<div class="bd">
<ul>
<li v-for="item in list">{{item}}</li>
</ul>
<Child52 />
</div>
</template>
<script setup>
import { ref, inject } from 'vue';
import Child52 from './Child_5.2.vue'
const list = inject('list');
</script>
<style lang="css" scoped>
</style>
父组件用provide来提供list数据,子组件用inject来接受父组件传来的值,孙子组件都可以用inject来接收
EventBus mitt插件(事件总线)
这个方法可以自己可以去查查看。
如觉得本文对你有帮助的话,欢迎点赞❤❤❤,写作不易,持续输出的背后是无数个日夜的积累,您的点赞是持续写作的动力,感谢支持!