vue3 的组件通信

1、props

props主要用于父组件向子组件通信。在父组件中通过用 :msg="msg" 绑定需要传给子组件的属性值,然后再在子组件中用 props 接收该属性值。

方法一:

// 父组件 传值
<child :msg1="msg1" :msg2="msg2"></child>
<script>
import child from "./child.vue";
import { ref, reactive } from "vue";
export default {
    setup() {
        //基础类型传值
        const msg1 = ref("父组件传给子组件的msg1");
        // 复杂类型(数组或对象)传值
        const msg2 = reactive(["父组件传给子组件的msg2"]);
        // const msg2 = reactive({"父组件传给子组件的msg2"});
        return {
            msg1,
            msg2
        }
    }
}
</script>

// 子组件 接收
<script>
export default {
  // props接受父组件传过来的值
  props: ["msg1", "msg2"],
  setup(props) {
    console.log(props);
    // { msg1:"父组件传给子组件的msg1", msg2:"父组件传给子组件的msg2" }
  },
}
</script>

方法二:使用 setup 语法糖

// 父组件 传值
<child :msg="msg">
</child>
<script setup>
    import child from "./child.vue";
    import { ref, reactive } from "vue";
    const msg = ref("父组件传给子组件的值");
    // const msg = reactive(["父组件传给子组件的值"]);
    // const msg = reactive({"父组件传给子组件的值"});
</script>

// 子组件 接收
<script setup>
    // 这里不需要在从vue中引入defineProps,直接用
    const props = defineProps({
        // 第一种写法
        msg: String;
        // 第二种写法
        msg:{
            type:String,
            default:""
        }
    })
    console.log(props);
</script>

2、$emit

$emit 也就是通过自定义事件传值,主要用于子组件向父组件通信

在子组件的点击事件中,通过触发父组件中的自定义事件,把想传给父组件的信息以参数的形式带过去,父组件便可以拿到子组件传过来的参数值。

// 子组件 派发
<template>
    <button @click="handleClick">按钮</buttom>
   // <button @click="emit('myClick')">按钮</buttom> 
</template>
<script setup>
    const handleClick = () => {
        // 触发父组件中的方法,并把值以参数的形式传过去
        // 这里触发的方法名要和父组件中@符后面的名称一样
        emit("myClick", "子组件向父组件传送的信息");
    }
    // const emit = defineEmits(["myClick","子组件向父组件传送的信息"]);
</script>

// 父组件 接收
<template>
    <child @myClick="onMyClick"></child>
</template>
<script setup>
    import child from "./child.vue";
    // 父组件接受到子组件传过来的值
    const onMyClick = (msg) => {
        console.log(msg);
    }
</script>

3、expose / ref

expose与ref 主要用于父组件获取子组件的属性或方法。在子组件中,向外暴露出属性或方法,父组件便可以使用 ref 获取到子组件身上暴露的属性或方法。

// 子组件
<script setup>
    // 方法一、使用expose对外暴露属性或方法
    ctx.expose({
        childName: "子组件的名称属性",
        childMethod(){
            console.log("子组件的方法");
        }
    })
    // 方法二,使用defineExpose
    //  defineExpose({
    //     childName: "子组件的名称属性",
    //     childMethod(){
    //         console.log("子组件的方法");
    //     }
    // })
</script>

// 父组件 
<template>
    <child ref="childRef"></child>
    <button @click="handlerClick">按钮</button>
</template>
<script setup>
    import child from "./child.vue";
    import { ref } from "vue";
    const childRef = ref(null);
    const handlerClick = () => {
        // 获取子组件对外暴露的属性
        const childName = childRef.value.childName;
        console.log(childName);
        // 调用子组件对外暴露的方法
        comp.value.childMethod();
    }
</script>

4、attrs

attrs 主要用于子组件获取父组件中没有通过 props 接收的属性

// 父组件 传值
<child :msg1="msg1" :msg2="msg2" title="子组件"></child>
<script setup>
    import child from "./child.vue";
    import { ref, reactive } from "vue";
    const msg1 = ref("信息1");
    const msg2 = ref("信息2");
</script>

// 子组件 接收
<script setup>
    // import { defineProps, useAttrs } from "vue";
    // 子组件接收msg1
    const props = defineProps({
        msg1: String
    })
    
    const attrs = useAttrs();
    // 因为子组件接收了msg1,所以打印的结果中不会包含msg1, { msg2:"信息1", title: "子组件" }
    // 如果子组件没有接收msg1,打印的结果就是 { msg1: "信息1", msg2:"信息12", title: "子组件" }
    console.log(attrs); 
</script>

5、provide / inject

provide与inject 主要为父组件向子组件或多级嵌套的子组件通信

provide:在父组件中可以通过 provide 提供需要向后代组件传送的信息。

inject:从父组件到该组件无论嵌套多少层都可以直接用 inject 拿到父组件传送的信息。

// 父组件
<script setup>
    import { provide } from "vue";
    // 父组件通过 provide 提供给子组件的信息
    provide("name", "提供给后代组件的信息");
</script>

// 子组件或后代组件(不管几级子组件)
<script setup>
    import { inject } from "vue";
    // 后代组件通过 inject 可以直接拿到父组件提供的信息
    const name = inject("name");
    console.log(name); 
</script>

6、 v-model

v-model 主要用于父子组件中多个数据的双向绑定

// 父组件
<child v-model:msg="msg" ></child>
<script setup>
    import child from "./child.vue";
    import { ref } from "vue";
    // v-model双向绑定
    const msg = ref("父组件中的msg");
</script>

// 子组件
<template>
    <button @click="handlerClick">按钮</button>
</template>
<script setup>
    // 子组件接收父组件传过来的属性值
    const props = defineProps({
      msg: {
        type: String,
        default: ''
      }
    })
    // 子组件通过emit更改父组件中msg的值
    const emit = defineEmits(['msg']);
    const handlerClick = () => {
       emit('update:msg', '子组件更新了的msg');
    }
</script>

还有一种就是使用 Vuex 仓库啦!

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值