@[TOC] 父子组件通信
本文主要是记录Vue3在setup语法糖下的父子组件间通信的四种方式
Vue3+TypeScript
父组件传值给子组件主要是由父组件为子组件通过v-bind绑定数值,而后传给子组件;子组件则通过defineProps接收使用。
父组件: 父组件中给要传给子组件的属性type直接赋值
子组件: 子组件里的props定义从父组件拿过来的属性名type, 从而拿到父组件传过来的属性值
const props = defineProps({
type: {
default: 'edit',
type: String,
},
});
父组件: 拿到子组件传过来的数据false给handleVisible方法里
function handleVisible(data:any) {
state.dialog.visible = data
}
子组件: 子组件中通过emit调用父组件中的changeVisible方法,给父组件的这个方法里传入数据false
if (state.type == 'create') {
addScene(state.formData).then(() => {
ElMessage.success(state.type == 'edit' ? t('message.modifySuccess') : t('message.addSuccess'));
emit('changeVisible', false)
cancel();
});
}
当父组件想直接使用子组件的属性或者方法时,子组件可以使用defineExpose暴露自身的属性或者方法。
父组件: 父组件通过ref定义子组件实例,通过调用实例获得子组件的属性和方法
//拿到子组件实例
const formChildrenRef = ref()
function cancel() {
resetForm();
state.dialog.visible = false;
// 调用子组件的方法
if(formChildrenRef.value) {
formChildrenRef.value.resetForm()
}
}
子组件: 子组件通过defineExpose暴露对象和方法
function resetForm() {
state.actions = []
state.conditions = []
state.actionTags = []
state.conditionsTags = []
state.formData = {
sceneName: '',
sceneType: 1,
identifierType: null,
enable: 1,
}
dataFormRef.value.resetFields();
i18nFormRef.value.formRef.resetFields();
}
defineExpose({
resetForm
})
在父子组件传递数据时,通常使用的是 props 和 emit,父传子时,使用的是 props,如果是父组件传孙组件时,就需要先传给子组件,子组件再传给孙组件,如果多个子组件或多个孙组件使用时,就需要传很多次,会很麻烦。
像这种情况,可以使用 provide 和 inject 解决这种问题,不论组件嵌套多深,父组件都可以为所有子组件或孙组件提供数据,父组件使用 provide 提供数据,子组件或孙组件 inject 注入数据。同时兄弟组件之间传值更方便。
如下为父组件Root.vue:
我是root组件
如下为子组件Footer.vue:
我是footer组件
接收父组件的值:{{getFatherValue}}
如下为孙子组件DeepChild.vue:
我是deepChild组件
接收爷爷组件的值:{{getGrandFatherValue}}
当最顶层的组件Root.vue传值给所有子组件时,使用provide进行注入
provide(/* 注入名 */ 'toChildValue', /* 值 */ toChildValue)
而后无论哪个子组件想要获取toChildValue的值,只需使用inject即可
inject>(/* 注入名 */"toChildValue",/* 默认值 */ ref(""))
为什么父子组件传值时有时用props不行,用provide可以?