外观
Vue 组件通信与 v-model
- 状态:未准备
- 适用方向:前端 / Go 全栈
- 最近复习:待填写
- 下次复习:待安排
一句话回答
Vue 组件通过 props 向下传值、emit 向上通知,用插槽定制内容、provide/inject 跨层传依赖;组件 v-model 本质是值 prop 与对应更新事件组成的协议。
原理解释
props 与 emit
props 是只读的下行输入,子组件不应直接改 prop 绑定。对象 prop 的嵌套成员可能仍能修改,但这会隐式改变父状态,通常应 emit 明确意图。组件事件不按 DOM 事件规则冒泡,祖先不能自动接到任意后代 emit。
vue
<!-- SearchInput.vue:Vue 3 通用写法 -->
<script setup lang="ts">
defineProps<{ modelValue: string }>()
const emit = defineEmits<{ (event: 'update:modelValue', value: string): void }>()
function onInput(event: Event) {
emit('update:modelValue', (event.target as HTMLInputElement).value)
}
</script>
<template>
<input :value="modelValue" @input="onInput">
</template>父组件 <SearchInput v-model="query" /> 对应传 modelValue 和监听 update:modelValue。Vue 3.4+ 可用 defineModel 简化声明;v-model:title 对应 title/update:title,可同时建立多个模型。给 defineModel 设置子组件默认值时,需留意父值为 undefined 产生的不同步。
插槽与跨层依赖
默认/具名插槽决定内容放在哪里;作用域插槽让子组件把数据交给父模板,父模板仍在父词法作用域里求值。provide/inject 用于主题、表单上下文等跨层依赖;注入普通值不会凭空变成响应式,可传 ref,并把修改集中在提供方。
属性透传与组件公开接口
未声明为 props/emits 的属性和监听器可成为透传属性;单根组件通常自动透传,多根组件需明确落点,可用 inheritAttrs 和 $attrs 控制。<script setup> 组件默认不公开内部绑定,需要父组件通过模板 ref 使用的方法可用 defineExpose 明确暴露。
场景与边界
Vue 3.5+ 对同一 <script setup> 中 defineProps 的解构读取提供编译期响应式转换;不能把这个特例推广成普通 reactive 解构也保留响应式。跨函数传递属性读取时,可传 () => props.id 这类 getter,而不是一次性取出的值。
项目中的应用
暂无 Vue 项目证据。可参照 SimulSpeak 控制栏与字幕视图 设计 props/emits:父组件拥有会话状态,控制栏发出开始/停止意图,视图接收只读展示数据。
常见追问
- v-model 破坏单向数据流吗? 它把 prop 与更新事件简写,状态归属仍应明确。
- 兄弟组件怎么通信? 提升状态到父组件或合适的共享 store;不要为少量共享就引入全局事件总线。
- provide/inject 与 Pinia 怎么选? 前者适合组件树内依赖,后者适合跨业务共享状态及相应工具支持。