Vue 3 —— F / 组件通信
① 添加:Header 内 `@keyup.enter` 非空校验后 `emit('add-todo',name)`适当时机 `emit('事件名',参数)`步骤:子用 `defineProps(['xxx'])` 接收;把组件当成 li 遍历,独立传值 `:key="id"` + 各 props;② 删除:Main 内点击销毁按钮 `emit('del-todo',index)`后代:`cons
Vue3 学习大纲(05 scoped + 组件通信 + props 校验 + 记事本组件版)
一、scoped 作用与原理
1. 默认样式全局生效,易造成组件间样式冲突
2. 解决方案:给 `<style>` 加 `scoped`
3. 原理:
① 编译时为组件内所有 DOM 添加唯一 data-v-hash 属性
② CSS 选择器追加交集 `[data-v-hash]`,保证样式仅作用于当前组件
4. 结论:推荐始终使用 scoped,避免污染
二、父子组件通信
1. 父 → 子(props)
步骤:子用 `defineProps(['xxx'])` 接收;父在子标签用 `:xxx="数据"` 传递
场景:列表项、商品卡片等数据不确定时提高复用性
2. 子 → 父(emit)
props 只读,子组件不能直接修改
步骤:
① 父在子标签绑定自定义事件 `@事件名="父改数据函数"`
② 子内部 `const emit = defineEmits()`;适当时机 `emit('事件名',参数)`
案例:砍价按钮点击,通知父组件把对应商品价格减去指定值
3. v-for 遍历组件
把组件当成 li 遍历,独立传值 `:key="id"` + 各 props;注意必须传 key
三、props 校验
1. 简易写法:`defineProps({ 属性: 类型 })`
2. 完整写法:
```
defineProps({
属性: {
type: String/Number/Boolean/Array/Object,
required: true,
default: 值 | () => 复杂默认值,
validator: (v) => 布尔
}
})
```
3. 注意:required 与 default 二选一;复杂类型 default 用函数返回
4. props vs 组件自身数据:props 只读,遵循单向数据流;ref/reactive 可读可写
四、记事本 Todo —— 组件化完整实战
1. 拆分结构
TodoHeader(输入+添加)
TodoMain(列表渲染+完成/删除)
TodoFooter(统计+清除已完成)
2. 数据管理
统一在根组件 App.vue 提供 `todoList` ref;通过 props 下发子组件
子组件需要改数据 → emit 事件 → 父组件执行增/删/改/清空
3. 功能闭环
① 添加:Header 内 `@keyup.enter` 非空校验后 `emit('add-todo',name)`
② 删除:Main 内点击销毁按钮 `emit('del-todo',index)`
③ 统计与清除:Footer 接收列表长度,点击 Clear 发出 `clear-todo` 事件
④ 持久化:父组件 `watch(todoList, 写入localStorage, {deep:true})`
4. 样式:直接复用 TodoMVC 官方 CSS,组件内无需额外编写
五、非父子组件通信
1. 祖先 → 任意后代 provide/inject
祖先:`provide('key', value)`
后代:`const value = inject('key')`
适合主题、语言等全局性数据
2. 任意两组件 EventBus(mitt)
创建中间人 `const emitter = mitt()`
发送方:`emitter.emit('事件名',数据)`
接收方:`emitter.on('事件名',回调)`
适合简单跨层级、兄弟通信;大型项目推荐 Pinia
六、章节口诀
“scoped 加属性选择器,样式不打架;
父传子 props,子传父 emit;
遍历组件像遍历 li,独立 key 值别落下;
props 能校验,类型必填自定义;
Todo 拆三块,数据父管子发话;
跨层 provide/inject,任意 mitt 拉呱。”
更多推荐

所有评论(0)