vue3父子组件间传参通信

@[TOC] 父子组件通信

前言

本文主要是记录Vue3在setup语法糖下的父子组件间通信的四种方式

Vue3+TypeScript

一、父传子— props

父组件传值给子组件主要是由父组件为子组件通过v-bind绑定数值,而后传给子组件;子组件则通过defineProps接收使用。

父组件: 父组件中给要传给子组件的属性type直接赋值

    
      
    

子组件: 子组件里的props定义从父组件拿过来的属性名type, 从而拿到父组件传过来的属性值

const props = defineProps({
    type: {
        default: 'edit',
        type: String,
    },

});

二、子传父— defineEmits

父组件: 拿到子组件传过来的数据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 (父组件调用子组件的方法)

当父组件想直接使用子组件的属性或者方法时,子组件可以使用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
})

四、依赖注入Provide / Inject

在父子组件传递数据时,通常使用的是 props 和 emit,父传子时,使用的是 props,如果是父组件传孙组件时,就需要先传给子组件,子组件再传给孙组件,如果多个子组件或多个孙组件使用时,就需要传很多次,会很麻烦。

像这种情况,可以使用 provide 和 inject 解决这种问题,不论组件嵌套多深,父组件都可以为所有子组件或孙组件提供数据,父组件使用 provide 提供数据,子组件或孙组件 inject 注入数据。同时兄弟组件之间传值更方便。

如下为父组件Root.vue:





如下为子组件Footer.vue:





如下为孙子组件DeepChild.vue:





当最顶层的组件Root.vue传值给所有子组件时,使用provide进行注入

provide(/* 注入名 */ 'toChildValue', /* 值 */ toChildValue)

而后无论哪个子组件想要获取toChildValue的值,只需使用inject即可

inject>(/* 注入名 */"toChildValue",/* 默认值 */ ref(""))

为什么父子组件传值时有时用props不行,用provide可以?

  1. 父组件通过props向子组件传递数据时,只能实现单向的数据流动,也就是说只能从父组件传递数据到子组件,而子组件无法直接修改父组件的数据。
  2. 而provide和inject是Vue提供的一种更加灵活的数据传递方式,可以实现从祖先组件向后代组件的跨层级传递数据,而且不受单向数据流的限制,后代组件可以直接修改祖先组件的数据。
  3. 这种方式更加适合非父子关系的组件通信,例如兄弟组件之间共享数据等。因此,使用provide和inject可以更加方便地实现组件之间的数据传递。

你可能感兴趣的:(前端,typescript)