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")//孙收
	}
相关推荐
梦境之冢37 分钟前
axios 常见的content-type、responseType有哪些?
前端·javascript·http
racerun40 分钟前
vue VueResource & axios
前端·javascript·vue.js
J总裁的小芒果1 小时前
THREE.js 入门(六) 纹理、uv坐标
开发语言·javascript·uv
m0_548514771 小时前
前端Pako.js 压缩解压库 与 Java 的 zlib 压缩与解压 的互通实现
java·前端·javascript
AndrewPerfect1 小时前
xss csrf怎么预防?
前端·xss·csrf
Calm5501 小时前
Vue3:uv-upload图片上传
前端·vue.js
浮游本尊1 小时前
Nginx配置:如何在一个域名下运行两个网站
前端·javascript
m0_748239831 小时前
前端bug调试
前端·bug
m0_748232921 小时前
[项目][boost搜索引擎#4] cpp-httplib使用 log.hpp 前端 测试及总结
前端·搜索引擎
新中地GIS开发老师1 小时前
《Vue进阶教程》(12)ref的实现详细教程
前端·javascript·vue.js·arcgis·前端框架·地理信息科学·地信