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")//孙收
	}
相关推荐
IT_陈寒2 分钟前
Python的多线程居然是个假把式?搞清GIL让我少熬三天夜
前端·人工智能·后端
宿6742 分钟前
vue3-config
前端·javascript·vue.js
明月_清风3 分钟前
位图与布隆过滤器:海量数据下的"存在性判断"艺术
前端·后端·算法
明月_清风11 分钟前
Hash 表从入门到精通:Go 实战与工程细节
前端·后端·算法
非凡ghost2 小时前
AI修图不“造假“,摄影师的出片效率加速器
服务器·前端·人工智能·电脑
2601_951615202 小时前
网页设计模板源码 web前端模板网页源码下载
前端
mmsx2 小时前
osmdroid 地图实战 03|地图的"分层世界":离线方案、图层模型与 Overlay 体系
android·前端
郭邯2 小时前
从零到一:我用 AI 写了个复利计算器,顺便治好了我的"公式恐惧症"
前端
Pointer Pursuit2 小时前
C++11特性(二)
前端·c++·算法
天道kabuto2 小时前
Vue3 升级踩坑:子组件 click 事件为什么会触发两次?
前端