vue3父子组件传值

一、vuex 实现组件传值

父子,子子,祖孙

二、setup语法糖

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

情况一:父传子收

1、父组件传值
  • 解构抛出
html 复制代码
<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属性设置默认值,在当前属性没有值传入时使用;
html 复制代码
<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并定义要给父组件的方法,数组内可定义多个方法
  • 第一个参数为要传递的事件名,第二个参数为要传递的值
html 复制代码
<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、父组件接收
  • 父组件中使用自定义事件接收,自定义事件名称必须与子组件传递的一致(即等号前面名称)
  • 等号后面的事件名称可自行定义
  • 事件中通过默认参数接收使用子组件传递的值
html 复制代码
<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、子组件
html 复制代码
<template>
    {{ name }}
</template>
<script setup>
    import { ref } from 'vue'
    const name = ref("张三")
    defineExpose({
        name
    });
</script>
5、父组件
html 复制代码
<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、父组件 ---通过 :自定义属性名="属性值" 的形式传递数据
html 复制代码
//父组件
<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属性设置默认值,在当前属性没有值传入时使用;
html 复制代码
//子组件
<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、父组件
javascript 复制代码
<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、子组件
javascript 复制代码
export default {
	name:"helloworld",
	setup(){
		//被父组件调用的方法
		function receive(val){
			console.log(val)
		}
		return{receive}
	}

情况二:子传父收

1、 子组件
  • setup函数中ctx的emit用于传递事件给父组件
  • 第一个参数为要传递的事件名,第一个参数为要传递的值
html 复制代码
<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、父组件接收
  • 父组件中使用自定义事件接收,自定义事件名称必须与子组件传递的一致(即等号前面名称)
  • 等号后面的事件名称可自行定义
  • 事件中通过默认参数接收使用子组件传递的值
html 复制代码
<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
javascript 复制代码
//进入页面即刻传值
<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
javascript 复制代码
export default {
	name:"helloworld",
	setup(){
		const res = inject("p")//孙收
	}
相关推荐
也无晴也无风雨1 小时前
深入剖析输入URL按下回车,浏览器做了什么
前端·后端·计算机网络
Martin -Tang2 小时前
Vue 3 中,ref 和 reactive的区别
前端·javascript·vue.js
FakeOccupational3 小时前
nodejs 020: React语法规则 props和state
前端·javascript·react.js
放逐者-保持本心,方可放逐3 小时前
react 组件应用
开发语言·前端·javascript·react.js·前端框架
曹天骄4 小时前
next中服务端组件共享接口数据
前端·javascript·react.js
阮少年、5 小时前
java后台生成模拟聊天截图并返回给前端
java·开发语言·前端
郝晨妤6 小时前
鸿蒙ArkTS和TS有什么区别?
前端·javascript·typescript·鸿蒙
AvatarGiser6 小时前
《ElementPlus 与 ElementUI 差异集合》Icon 图标 More 差异说明
前端·vue.js·elementui
喝旺仔la6 小时前
vue的样式知识点
前端·javascript·vue.js
别忘了微笑_cuicui6 小时前
elementUI中2个日期组件实现开始时间、结束时间(禁用日期面板、控制开始时间不能超过结束时间的时分秒)实现方案
前端·javascript·elementui