Vue.js框架:vue3版本父子组件之间的传值和事件触发

一、子组件

  使用vue3官方提供的setup语法糖中给出的defineEmitsdefineProps、defineExpose来定义父子间的传参值和关联方法(useContext在3.2版本之后已去除)。

    <script setup lang="ts">
    const emitEvents = defineEmits(['son-click'])
    const props = defineProps({
        message: String
    })
    defineExpose({
        getName(){
            return "张三";
        },
        age: 23
    })

    const sonClick = () =>{
        emitEvents('son-click',"子组件返值")
    }
    </script>
    <template>
        <div>
            <div>
                测试父组件->子组件传值消息:{{ props.message }}
            </div>
            <el-button type="primary" @click="sonClick">
                测试按钮
            </el-button>
        </div>
    </template>

二、父组件

  父组件中引入子组件,并在使用子组件时传参和定义子组件中事件的回调方法。

    <script setup lang="ts">
    import { onMounted, ref } from "vue"
    import Son from "./SonComponent.vue"

    let sonMessage = ref("")
    const fatherClick = (context) => {
        sonMessage.value = context;
    }

    let son = ref()
    let sonAge : any = ref()
    let sonName : any  = ref()
    onMounted(() => {
        sonAge.value = son.value?.['age']
        sonName.value = son.value?.['getName']()
    })

    </script>
    <template>
        <Son ref="son" message="父组件传值" @son-click="fatherClick"></Son>
        <br />    
        <div>
            测试子组件->父组件传值消息:{{ sonMessage }}
        </div>
        <br />    
        <div>
            子组件暴露值(名称):{{ sonName }}
        </div>
        <br />    
        <div>
            子组件暴露值(年龄):{{ sonAge }}
        </div>
    </template>

  注:defineExpose里的方法和数据,要在父组件的onMounted生命周期里取用,在这之前是取不到数据的,而且定义时需要将存储数据的属性定义为响应式数据,便于页面回显。

三、运行结果

  父组件传值在初始化时直接给到子组件,点击子组件的按钮后通过回调返回到父组件进行展示:

  

四、数据流转

  1、父->子传递message参数

  

  2、子->父传递sonMessage参数

  

  3、子->父传递getName方法和age参数

  

五、扩展(祖孙组件传值)

  祖组件如果想要传值给孙组件的话,按照祖传父、父传子的递进关系也可实现,但是从代码角度来说,父组件用不到这个参数,多写一套逻辑很冗余。

  因此最好是在祖孙组件之间直接传值,祖组件使用provide方法提供数据,孙组件使用inject方法收取数据进行使用

  1、祖组件

    <script setup lang="ts">
    import { provide, reactive } from "vue";
    import Father from "./components/FatherComponent.vue"
    let grandFather = reactive({
      message:"来自祖父组件传值"
    })
    provide('grandFather',grandFather)
    </script>

    <template>
      <Father></Father>
    </template>

  在祖组件中通过reactive定义了一个响应式数据grandFather,里面携带有属性message

  使用provide方法将该响应式数据放至同名的属性中。

  2、孙组件

    <script setup lang="ts">
    import { inject } from 'vue';
    const grandSon : any = inject('grandFather',{})</script>
    <template>
        <div>
            <div>
                测试祖组件->孙组件传值消息:{{ grandSon.message }}
            </div>
        </div>
    </template>

  在孙组件中通过inject接受响应式数据grandFather里并命名为grandSon,它的首个参数为接受数据的名称,第二个参数定位为当没有接到数据时的默认值这里设置为{}空表单,防止页面渲染数据时因空报错

  grandSon数据格式定义为any,避免校验问题,否则下面grandSon.message会爆红(数据能接到,但是爆红不得劲)。

  3、结果如下

  

 

posted @ 2023-10-23 08:33  我命倾尘  阅读(2477)  评论(0编辑  收藏  举报