目录
一、Vue3 父子传值(核心 2 种,简洁示例)
1. 父 → 子:props(向下传值,只读)
实现(组合式 API,<script setup>)
<!-- 父组件 Parent.vue -->
<template>
<Child :msg="parentMsg" :user="parentUser" />
</template>
<script setup>
import { ref, reactive } from 'vue';
import Child from './Child.vue';
// 要传递的数据
const parentMsg = ref('父组件传递的文本');
const parentUser = reactive({ id: 1, name: '张三' });
</script>
<!-- 子组件 Child.vue -->
<template>
<p>{{ msg }}</p>
<p>{{ user.name }}</p>
</template>
<script setup>
// 定义 props 接收(对象校验更规范,简洁可写数组 ['msg', 'user'])
const props = defineProps({
msg: String,
user: { type: Object, default: () => ({}) }
});
// 注意:props 只读,不能直接修改!
</script>
2. 子 → 父:emit 自定义事件(向上传值,单向数据流)
实现(组合式 API,<script setup>)
<!-- 父组件 Parent.vue -->
<template>
<p>父组件计数:{{ count }}</p>
<Child @add="handleAdd" />
</template>
<script setup>
import { ref } from 'vue';
import Child from './Child.vue';
const count = ref(0);
// 接收子组件参数,修改自身数据
const handleAdd = (step) => {
count.value += step;
};
</script>
<!-- 子组件 Child.vue -->
<template>
<button @click="emitAdd">+1</button>
</template>
<script setup>
// 定义可触发的事件
const emit = defineEmits(['add']);
const emitAdd = () => {
// 触发事件,传递参数
emit('add', 1);
};
</script>
补充:双向绑定简化(v-model,语法糖)
<!-- 父组件 -->
<Child v-model:count="count" />
<!-- 子组件 -->
<script setup>
const props = defineProps(['count']);
const emit = defineEmits(['update:count']);
// 触发更新,实现双向绑定
emit('update:count', props.count + 1);
</script>
二、高频面试题(精简版,含核心答案)
-
Vue3 父子组件如何传值?(核心必问)
- 答案:① 父 → 子:用
props【Pro普死】,子组件通过defineProps【敌分死Pro普死】接收,props只读不可直接修改;② 子 → 父:用emit【e们特】自定义事件,子组件defineEmits声明事件,emit触发并传参,父组件绑定事件处理。
- 答案:① 父 → 子:用
-
props为什么是只读的?修改props会怎么样?- 答案:遵循 Vue 「单向数据流」原则,防止子组件篡改父组件数据,导致数据流向混乱、难以调试。直接修改会控制台报错,且修改无效(仅开发环境提示,生产环境不阻止但不推荐)。
-
子组件想修改父组件传递的数据,该怎么做?
- 答案:不能直接修改,有 2 种方式:① 子组件通过
emit触发父组件事件,由父组件自行修改数据(推荐);② 父组件传递一个「修改数据的方法」(如响应式对象的方法),子组件调用该方法修改。
- 答案:不能直接修改,有 2 种方式:① 子组件通过
-
props传递对象/数组时,子组件修改内部属性,父组件会同步更新,为什么?- 答案:
props只读限制的是「引用地址」,对象/数组是引用类型,子组件修改内部属性不会改变引用地址,因此会同步更新父组件数据。但这种做法违背单向数据流,不推荐,仍需通过emit通知父组件修改。
- 答案:
-
Vue3 中
defineProps和defineEmits不需要导入就能使用,为什么?- 答案:在
<script setup>语法中,Vue 会自动注入这两个编译宏,它们是编译阶段的语法糖,不是运行时 API,因此无需手动导入,且不能在普通<script>中使用。
- 答案:在
三、总结
- 父 → 子核心是
props(只读、向下传递),子 → 父核心是emit(自定义事件、向上通知)。 - 面试答题紧扣「单向数据流」原则,这是 Vue 父子传值的核心思想。
- 简化用法可使用
v-model语法糖,快速实现双向绑定效果。
浙公网安备 33010602011771号