| [组件](组件.md) | - Components `Basics<br>`- Components In-`Depth<br>`- `Registration<br>`- [props](props.md)<br>- `Events<br>`- Component v-`model<br>`- Fallthrough `Attributes<br>`- [Slots](Slots.md)<br>- Provide / `inject<br>`- Async Components | |
| ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --- |
## 两种风格
Composition API/组合式 比 Options API / 选项式
- 使用 `<script setup>` 代替了 `export default { setup() {... } }`。
- 所有的变量和函数都直接在顶层定义,不需要放在 `setup()` 函数中。
- 不需要显式地返回要暴露给模板的变量和函数,它们会自动暴露。
## 响应式
[观察者模式](观察者模式.md)
- 被观察的数据(Ref/Reactive对象)
- 保存实际的数据
- 维护一个依赖列表(Dep)
- 当数据变化时通知依赖列表中的所有观察者
- 观察者(Effect)
- 可以是[模板渲染](模板渲染.md)函数
- 可以是watch回调
- 可以是computed计算属性
- 响应数据变化并执行相应的更新操作
一个简单的 ref 对象在内部大概是这样的:
```js
{
"value": "实际的值",
"__v_isRef": true,
"__v_isShallow": false,
"dep": {
"w": 0,
"n": 0,
"m": new Map()
}
}
```
## 父子双向通信
- [props](props.md) 是父组件给子组件的数据
- [Emits](Emits.md) 是子组件给父组件暴露的按钮、事件
这两种机制一起,形成了 Vue 组件之间的双向通信系统,使得组件可以很好地协同工作,同时保持相对独立和可复用。
### 父组件
1. 导入组件
2. 注册组件,将导入的组件注册到当前组件的 `components` 选项中,使其可以在模板中使用。
3. 使用组件,并传递了多个 props 和事件处理函数。

### 子组件
### 数据,冒号开头
1. provide/inject 方式:
- 用于跨多层组件传递数据
- 子组件可以直接修改值(如果传递的是 ref/reactive)
- 耦合性较强,子组件需要知道依赖注入的具体名称
- 适用于深层组件通信
```js
// 父组件
provide('showResults', showResults); // 提供响应式引用
// 子组件
const showResults = inject('showResults'); // 获取响应式引用
```
1. Props 方式:
- 用于父子组件之间的直接通信
- 遵循单向数据流,子组件不能直接修改 props
- 更明确的组件接口定义
- 更容易追踪数据流向
- 适用于直接的父子组件通信
```js
// 父组件
<MappingGridCard :show-results="showResults.value" />
// 子组件
const props = defineProps({
showResults: Boolean
});
```
### 动作,@开头
1. 事件函数
1. 子组件触发 'search' 事件。
2. 父组件的 handleSearch 方法被调用。
3. handleSearch 执行异步操作(调用 querySuccess)。
4. 子组件的 await emit(...) 等待这个异步操作完成。
5. 异步操作完成后,子组件继续执行,重置 isSearching 状态。


## 如何在父中改造子组件?
[插槽v-slot](插槽v-slot)