vue3父子组件传值

一、vuex 实现组件传值

父子,子子,祖孙

二、setup语法糖

<!-- 使用组件,通过 :自定义属性名="属性值" 的形式传递数据 -->
<!-- 属性值 是defineProps中的数据-->
<children :le="text" :list="list"></children>

情况一:父传子收

1、父组件传值
  • 解构抛出
<template>
    <div class="father">
        <h1>父组件</h1>
        <span>{{text}}</span>
    </div>
    <div class="box">
        <!-- 使用组件,通过 :自定义属性名="属性值" 的形式传递数据 -->
        <children :le="text" :list="list"></children>
    </div>
</template>
<script setup>
    // 引入
    import {reactive, toRefs,} from 'vue';
    // 引入组件
    import children from "./views/children";
    const data = reactive({
        text: '文字',
        list: [1, 2, 3, 4, 5]
    })
    // 解构抛出
    const {text, list} = toRefs(data)
</script>
<style scoped>
    .father {
        width: 100%;
        height: 200px;
        background: red;
    }

</style>
2、子组件
  • 通过defineProps()可接收父组件传递的值;
  • type属性定义接受的数据类型;
  • default属性设置默认值,在当前属性没有值传入时使用;
<template>
    <div class="box">
        <h1>子组件</h1>
        <div>{{ le }}</div>
        <div v-for="item in list">{{ item }}</div>
    </div>
</template>
<script setup>
    // 引入
    import { defineProps } from 'vue';
    // 解构数据
    const { le, list } = defineProps({
        le: {
            type: String, // 接收的参数类型
            default: '默认文字', //默认值
        },
        list: {
            type: Array, // 接收的参数类型
            default: [], //默认值
        }
    })
</script>
<style scoped>
    .box{
        width: 100%;
        height: 200px;
        background: #25A4BB;
    }
</style>

情况二:子传父收

方法一 :defineEmits 需要点击
1、 子组件传值
  • 调用defineEmits并定义要给父组件的方法,数组内可定义多个方法
  • 第一个参数为要传递的事件名,第二个参数为要传递的值
<template>
    <div class="box">
        <h1>子组件</h1>
        <div>{{ le }}</div>
        <button @click="giveFather">点击传值给父</button>
    </div>
</template>
<script setup>
    // 引入defineEmits
    import { reactive, defineEmits } from 'vue';
    // 接收defineEmits
    const emits=defineEmits()
    const data = reactive({
        text: '文字',
    })
    function giveFather() {
        // 第一个参数为要传递的事件名,第二个参数为要传递的值
        emits('giveFather', data.text)
    }

</script>
<style scoped>
    .box{
        width: 100%;
        height: 200px;
        background: #25A4BB;
    }
</style>
2、父组件接收
  • 父组件中使用自定义事件接收,自定义事件名称必须与子组件传递的一致(即等号前面名称)
  • 等号后面的事件名称可自行定义
  • 事件中通过默认参数接收使用子组件传递的值
<template>
    <div class="father">
        <h1>父组件</h1>
        <span>{{text}}</span>
    </div>
    <!-- 父组件中使用自定义事件接收,自定义事件名称必须与子组件传递的一致(即等号前面名称) -->
    <!-- 等号后面的事件名称可自行定义 -->
    <children @giveFather="receiveSon"></children>

</template>
<script setup>
    // 引入
    import {reactive, toRefs,} from 'vue';
    // 引入组件
    import children from "./views/children";

    const data = reactive({
        text: '',
    })

    function receiveSon(e) {
        // 通过默认参数接收使用子组件传递的值
        console.log(e);
        data.text = e
    }

    //解构数据
    const {text} = toRefs(data)

</script>
<style scoped>
    .father {
        width: 100%;
        height: 200px;
        background: red;
    }

</style>
方法二 :defineExpose
1、子组件
<template>
    {{ name }}
</template>
<script setup>
    import { ref } from 'vue'
    const name = ref("张三")
    defineExpose({
        name
    });
</script>
5、父组件
  • children.value.name 必须在函数中
<template>
    <child ref="children"></child>
    <button @click="aaa"> 点击</button>
</template>
<script setup>
    import { ref } from 'vue'
    import child from './views/children'
    const children = ref(null)
    function aaa(){
        console.log(children.value.name)	// "张三"
        		// "我叫张三"
    }
</script>


三、setup 函数方式

情况一:父传子收

方法一 利用props 刷新便可以传值
1、父组件 —通过 :自定义属性名=“属性值” 的形式传递数据
//父组件
<template>
    <div class="father">
        <h1>父组件</h1>
        <span>{{text}}</span>
    </div>
    <div class="box">
        <!-- 使用组件,通过 :自定义属性名="属性值" 的形式传递数据 -->
        <children :le="text" :list="list"></children>
    </div>
</template>
<script>
    // 引入
    import { reactive, toRefs, } from 'vue';
    // 引入组件
    import children from "./views/children";
    export default {
        name: 'app',
        // 注册组件
        components: {
            children
        },
        setup() {
            const data = reactive({
                text: '文字',
                list: [1, 2, 3, 4, 5]
            })
            return {
                // 解构抛出
                ...toRefs(data),
            }
        }
    }
</script>
<style scoped>
    .father{
        width: 100%;
        height: 200px;
        background: red;
    }

</style>

2、 子组件接收
  • props接受父传递的数据;
  • type属性定义接受的数据类型;
  • default属性设置默认值,在当前属性没有值传入时使用;
//子组件
<template>
    <div class="box">
        <h1>子组件</h1>
        <div>{{ le }}</div>
        <div v-for="item in list">{{ item }}</div>
    </div>
</template>
<script>
    // 引入
    import { defineComponent } from 'vue';
    // 加上defineComponent()之后,可以获得vue2、vue3的自动提示---可有可无
    export default defineComponent({
        name: 'children',
        props: {
            le: {
                type: String, // 接收的参数类型
                default: '默认文字', //默认值
            },
            list: {
                type: Array, // 接收的参数类型
                default: []  //默认值
            }
        },
        // props 是一个对象,包含父组件传递给子组件的所有数据。
        // context :上下文,包括 attrs 、 emit 、slots。
        setup(props, context) {
            console.log(props.le, props.list[0]);
        },
    })
</script>
<style scoped>
    .box{
        width: 100%;
        height: 200px;
        background: #25A4BB;
    }
</style>


方法二、 父组件中调用子组件的方法
1、父组件
<template>
	<helloworld ref ="val"/>//在父组件中找到子组件的节点
</template>
<script>
import {reactive,ref} from "vue"
import helloworld from "组件路径"
export default {
	compoents:{
		helloworld
	}setup() {
		const val = ref()
		const p1 = reactive({name:"小宋",age:12})
		function btn(){//点击事件调用子组件的方法
			val.vlaue.receive(p1)
		}
		return{btn,val}
}
</script>
2、子组件
export default {
	name:"helloworld",
	setup(){
		//被父组件调用的方法
		function receive(val){
			console.log(val)
		}
		return{receive}
	}

情况二:子传父收

1、 子组件
  • setup函数中ctx的emit用于传递事件给父组件
  • 第一个参数为要传递的事件名,第一个参数为要传递的值
<template>
    <div class="box">
        <h1>子组件</h1>
        <button @click="giveFather">点击传值传给父</button>
    </div>
</template>
<script>
    // 引入
    import { reactive, defineComponent } from 'vue';
    // 加上defineComponent()之后,可以获得vue2、vue3的自动提示
    export default defineComponent({
        name: 'child',
        // props 是一个对象,包含父组件传递给子组件的所有数据。
        // ctx :上下文,包括 attrs 、 emit 、slots。
        setup(props, ctx) {
            const data = reactive({
                text: '文字',
            })
            function giveFather() {
                // ctx中的emit用于传递事件给父组件
                // 第一个参数为要传递的事件名,第一个参数为要传递的值
                ctx.emit('giveFather', data.text)
            }
            return {
                // setup函数中定义事件需要抛出才能使用
                giveFather
            }
        },
    })
</script>
<style scoped>
    .box{
        width: 100%;
        height: 200px;
        background: #25A4BB;
    }
</style>


2、父组件接收
  • 父组件中使用自定义事件接收,自定义事件名称必须与子组件传递的一致(即等号前面名称)
  • 等号后面的事件名称可自行定义
  • 事件中通过默认参数接收使用子组件传递的值
<template>
    <div class="father">
        <h1>父组件</h1>
        <div>{{ cont }}</div>
    </div>
    <div class="box">
        <!-- 父组件中使用自定义事件接收,自定义事件名称必须与子组件传递的一致(即等号前面名称) -->
        <!-- 等号后面的事件名称可自行定义 -->
        <children @giveFather="receiveSon"></children>
    </div>
</template>
<script>
    // 引入
    import { reactive, toRefs, } from 'vue';
    // 引入组件
    import children from "./views/children";
    export default {
        name: 'app',
        // 注册组件
        components: {
            children
        },
        setup() {
            const data = reactive({
                cont: '',
            })
            function receiveSon(e) {
                // 通过默认参数接收使用子组件传递的值
                data.cont = e
            }
            return {
                // 解构抛出
                ...toRefs(data),
                // 抛出事件
                receiveSon
            }
        },

    }
</script>
<style scoped>
    .father{
        width: 100%;
        height: 200px;
        background: red;
    }

</style>

情况三:祖传孙收

1、祖组件----利用provide
//进入页面即刻传值
<template>
	<helloworld/>
</template>
<script>
import {reactive} from "vue"
import helloworld from "组件路径"
export default {
	compoents:{
		helloworld
	}setup() {
		const p1 = reactive({name:"小宋",age:12})
		provide("p",p1)//祖传 第一个参数是子组件用来识别的参数
	}
}

//点击传值

2、子组件–inject
export default {
	name:"helloworld",
	setup(){
		const res = inject("p")//孙收
	}
  • 15
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值