vuejs3.0 从入门到精通——组件传值方式1——props/$emit(父子传值 )

组件传值方式1 —— props / $emit(父子传值 )

一、父传子

1.1、父组件通过 props 传递数据

    在父组件中,创建了一个名为List的子组件实例,并通过:msg="msg"语法将父组件的msg数据传递给子组件。这里的msg是一个响应式引用(使用ref创建),初始值为'这是父传过去的数据'

<template>
    <div>
        <List :msg="msg"></List>
    </div>
</template>

<script setup lang="ts">
import List from '@/components/List.vue'
import { ref } from 'vue'
let msg = ref('这是父传过去的数据');
</script>
    • :msg="msg":这里的冒号(:)是v-bind:的简写(详细见:https://vuejs.org/api/built-in-directives.html#v-bind),用于动态绑定一个或多个属性,或组件 prop 到表达式的计算值。在这个例子中,它将 msg prop 绑定到msg的当前值。
    • ref:是 Vue 3 中的响应式 API 的一部分,用于创建一个响应式的引用。

1.2、子组件

    在子组件中,使用了defineProps函数来定义接收的 props,这里定义了 msg 这个 prop,并指定了它的类型和默认值。

<template>
    <div>
        这是子组件 ==> {{ msg }}
    </div>
</template>

<script setup lang="ts">
defineProps({       //defineProps 是用来定义组件的 props 的一个函数
    msg: {          //msg 是这个组件接收的一个 prop,它有以下属性
        type: String,       //表示这个 prop 的类型应该是字符串
        default: 'hello',   //表示如果没有提供这个 prop, 那么它的默认值会是 'hello'
    }
})
</script>
    • defineProps:是 Vue 3 Composition API 的一部分,用于在 setup 函数中定义组件的 props。它允许你以类型安全的方式定义 props,并提供了对默认值和验证的支持。
    • msg:是定义的一个 prop,它的类型是 String,这表示这个 prop 应该接收一个字符串。如果没有传递任何值,那么它的默认值会是 'hello'。
    • 在模板中,通过 {{ msg }} 语法,将接收到的 msg prop 显示出来。

二、子传父

  在 Vue 3 中,子组件向父组件传递数据的一种常见方式是通过$emit派发事件。

2.1、子组件中通过$emit派发事件

    在子组件中,你可以使用$emit方法来触发一个自定义事件。你可以在这个事件中传递任何你想要传递给父组件的数据。

2.1.1、使用$emit的注意事项

    • 确保在子组件中触发的事件名与父组件中监听的事件名保持一致。
    • 如果在子组件的 setup 方法中使用$emit,确保从 setup 函数的参数中获取 emit 函数。
    • 在使用$emit时,确保事件名和参数是有效的和有意义的,以便于代码的可读性和维护性。
<template>
    <div>
    // 这里定义了一个子组件的模板。它包含一个显示 num 的文本。
        这是子组件 ==> {{ num }}
    //这里定义了一个子组件的模板。它包含一个 button 按钮。
    //按钮上有一个 @click 监听器,它会在按钮被点击时触发 changeNum 方法。
        <button @click='changeNum'>按钮</button>
    </div>
</template>

<script lang="ts">
import { defineComponent, ref } from 'vue';
export default defineComponent({
    setup(_, { emit }) {
        let num = ref(100); // num 是一个响应式引用,初始值为100
        const changeNum = () => {
            emit('fn', num.value);  // 触发一个名为 'fn' 的自定义事件,并传递 num 的当前值
        }
        return {
            num, // 把 num 暴露给模板
            changeNum // 把 changeNum 方法暴露给模板
        }
    }
});
</script>

2.1.2、父组件中监听子组件的事件

    在父组件的模板中,可以监听子组件触发的自定义事件。当监听到这个事件时,可以调用父组件中的一个方法来处理这个事件。

<template>
    <div>
        //@fn 是监听子组件触发的名为 fn 的事件。当这个事件被触发时,它会调用名为 handleFn 的父组件方法
        <child-component @fn="handleFn"></child-component>
    </div>
</template>

<script lang="ts">
import ChildComponent from '@/components/List.vue'
export default {
    components: {
        ChildComponent
    },
    methods: {

        //payload 就是子组件通过 $emit 传递的数据
        handleFn(payload: number) {
            // 打印子组件传递的数据
            console.log('Received payload:', payload);
        }
    }
}
</script>

另外一种实现方式 <script setup lang=‘ts’>

2.2 A组件(Child)

<template>
    <div>
        <h1>{{ str }}</h1>
        <button @click="changeA">按钮</button>
    </div>
</template>

<script setup lang='ts'>

//从 Vue 库中导入 ref 函数。ref 是 Composition API 的一部分,用于创建响应式引用。
import { ref } from 'vue';

//创建一个响应式引用 str,并初始化为字符串 "这是A组件的数据"。
let str = ref('这是A组件的数据');

/*
    使用 defineEmits 函数定义一个名为 fn 的自定义事件。
    该组件就可以向外发送名为 fn 的事件,并传递数据。
*/
const emit = defineEmits(['fn']);

/*
    定义一个 changeA 方法。
    当该方法被调用时(比如点击按钮),它会使用 emit 发送一个 fn 事件,并传递当前 str 的值。
*/
const changeA = () => {
    emit('fn', str);
};
</script>

2.3 父组件

<template>
    <div>
        <A @fn="handleFn"></A>
        <B></B>
    </div>
</template>

<script setup lang="ts">
import A from './A.vue'
import B from './B.vue'

const handleFn = (payload: any) => {
    console.log('Received payload:', payload);
};
</script>
posted @ 2023-11-02 17:21  左扬  阅读(237)  评论(0编辑  收藏  举报
levels of contents