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 到表达式的计算值。在这个例子中,它将msgprop 绑定到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>

浙公网安备 33010602011771号