Vue3 父子组件互相调用方法,以及互相传值

 先简单的总结一下,后面有一个示例。

父组件:

1. 需要给子组件定义一个引用名

const mychild = ref(null);  //名字随意

2 .传递方式是直接使用标签:

<子组件 ref="引用名(mychild)" :数据名="父组件数据名" :方法名="父组件方法名" /?

3. 调用和接收子组件 (子组件需要使用defineExpose):

引用名(mychild).value.子组件数据名
引用名(mychild).value.子组件方法名()
子组件:

1. 接收父组件的数据和方法,需要定义一个defineProps,假设对象名=props:

let props  = defineProps({
            数据名: {
                type: Object, //也可是String等,跟父组件的数据类型一致
                default: ()=>{}
            },
            方法名:{
                type: Function
            }
        });

2. 调用父组件方法,用上一步的defineProps对象直接调用:

props.父组件方法名()

3. 子组件要传值和传方法给父组件,需要使用defineExpose()方法暴露给父组件:

defineExpose({子组件数据名, 子组件方法名})

示例:

父组件,只有一个按钮,用于测试调用子组件的方法,和接收子组件的数据。
子组件,1. 有一个表格显示来自父组件的数据。 2.一个按钮,用于测试调用父组件的方法。

直接贴上完整代码,我已经做了非常详细的注释:

父组件Parent.vue:

<template>
    <div style="border: solid 2px black;">
        <h2>我是父组件</h2>
        <input type="button" value="点我调用子组件方法" @click="testChild" />
    <br />
    <div style="margin: 10px; background-color: lightgray;">
        <child ref="mychild" :dataTochild="dataTochild" :parentFunc="parentFunc"/>
    </div>
    </div>
  </template>

<script lang="ts" setup>
import {reactive,ref} from 'vue'

//region 传给子组件使用的数据和方法 begin

定义子组件的引用 (ref="")
const mychild = ref(null); 

 定义在父组件的方法和数据
 通过下面的方式,分别传递给子组件
 <child ref="mychild" :dataTochild="dataTochild" :parentFunc="parentFunc"/>
const parentFunc=()=>{
    console.log("我是父组件的方法")
}

const dataTochild = reactive({
    time: Date(),
    info:{
            name:"admin",
            sex:"男"
         } 
})

//region 传给子组件使用的数据和方法 end

//region 定义在父组件,用于测试父组件调用子组件的方法,和接收来自子组件的数据 begin
const testChild=()=>{
    console.log("test from child!");
    mychild.value.childFunc();
    console.log(mychild.value.dataToParent)
}
//region 定义在父组件,用于测试父组件调用子组件的方法,和接收来自子组件的数据 end

</script>
<script lang="ts" >
import child from '../components/child.vue'
</script>

子组件Child.vue:

<template>
    <h3>我是子组件</h3>
        <table border="1px">
            <tr>
                <th colspan="2">
                    <span>下面的数据来自父组件</span>
                </th>
            </tr>
            <tr>
                <th>姓名</th>
                <th>性别</th>
            </tr>
            <tr>
                <td><span>{{dataTochild.info.name}}</span></td>
                <td><span>{{dataTochild.info.sex}}</span></td>
            </tr>
            <tr>
                <td colspan="2"><span>{{dataTochild.time}}</span></td>
            </tr>
            <tr>
                <td colspan="2"><input type="button" value="点我调用父组件方法" @click="testParent" /></td>
            </tr>
        </table>
    </template>
    <script setup lang="ts">
        import {ref} from 'vue'
        //region 给父组件调用的方法和数据 begin
         定义完成后,用defineExpose()暴露给父组件
        const childFunc = ()=>{
            console.log("我是子组件的方法");
        };
        const dataToParent = ref("我是子组件的数据");

        defineExpose({
            childFunc,dataToParent
        });
        //region 给父组件调用的方法和数据 end
    
        //region 接收自父组件的数据 begin
        let props  = defineProps({
            dataTochild : {
                type: Object,
                default: ()=>{}
            },
            parentFunc:{
                type: Function
            }
        });
        //region 接收自父组件的数据 end
    
        //region 定义在子组件,用于测试子组件调用父组件的方法 begin
        const testParent=()=>{
            console.log("test from parent!");
            props.parentFunc()
        }
        //region 定义在子组件,用于测试子组件调用父组件的方法 end
    </script>

测试结果:


 

Vue 2中,如果你想要实现在子组件关闭时触发父组件的刷新操作,通常会通过事件(Event)或者Vuex状态管理来实现。这里是一个简单的例子: 1. **通过事件($emit)递**: 子组件中,在关闭按钮的点击事件处理函数里,你可以使用`this.$emit(&#39;close-subpage&#39;)`来发射一个自定义事件,然后在父组件的模板上监听这个事件,并在接收到后调用`funA`。 ```javascript // 子组件.vue <template> <button @click="closeSubpage">关闭</button> </template> <script> export default { methods: { closeSubpage() { this.$emit(&#39;close-subpage&#39;); } } } </script> // 父组件.vue <template> <child-component @close-subpage="refreshPage"></child-component> </template> <script> import ChildComponent from &#39;./ChildComponent.vue&#39;; export default { components: { ChildComponent }, methods: { refreshPage() { this.funA(); } } }; </script> ``` 2. **利用Vuex**: 如果你的应用使用了Vuex,可以在关闭子组件时发送一个action到store,更新状态并触发派发(dispatch),在父组件中监听这个状态变化来刷新页面。 ```javascript // store.js 或者相应的模块 actions: { closeSubpage({ commit }) { commit(&#39;CLOSE_SUBPAGE&#39;); } }, mutations: { CLOSE_SUBPAGE(state) { // 更新状态... this.$root.$emit(&#39;refresh-page&#39;); // 或者使用其他方式通知父组件 } } // 父组件.vue <template> <button @click="openSubpage">打开</button> </template> <script> import { mapActions } from &#39;vuex&#39;; export default { methods: { ...mapActions([&#39;closeSubpage&#39;]), openSubpage() { this.$refs.subpage.open(); }, funA() { this.$forceUpdate(); // 刷新页面 } } }; </script> ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值