Skip to content

Lesson 006|Component 是什么?为什么逻辑要挂在组件上?

Tags: #Creator2.x #Component #Node #Enabled #UpdateDifficulty: ⭐⭐☆☆☆


🎯 本课目标

  • 理解 Component 是挂在 Node 上的能力
  • 理解为什么业务逻辑要写在 Component 中
  • 理解 node.activecomponent.enabled 的区别
  • 理解为什么空 update() 也有成本

🧩 上节课回顾

上一课我们讲了:

text
Node 是场景树里的空间对象。
Node 负责位置、旋转、缩放、父子关系、active、事件和组件挂载。
Component 是挂在 Node 上的能力。
Node 决定“在哪里”,Component 决定“做什么”。

💡 Component 是什么?

在 Cocos Creator 中,Component 可以理解成:

挂在 Node 上的一种能力。

例如:

text
StartButton
├── Sprite
├── Button
└── StartGameScript

含义是:

text
StartButton:Node,负责位置、层级、active、组件挂载
Sprite:Component,负责显示图片
Button:Component,负责按钮交互
StartGameScript:Component,负责开始游戏业务逻辑

所以:

text
Node = 容器
Component = 能力

🧠 为什么逻辑要挂在 Component 上?

Node 只负责空间和结构,不应该承担具体业务。

例如开始游戏逻辑:

ts
onClickStart () {
    cc.director.loadScene("Game");
}

这段逻辑不属于 Node,也不属于 Sprite,而应该属于 StartGameScript 这个 Component。

这样职责清晰:

text
Sprite:显示
Button:交互
StartGameScript:业务逻辑

🔍 Component 常见类型

渲染组件

text
cc.Sprite
cc.Label
cc.Graphics
cc.RichText

负责产生可见内容。

交互组件

text
cc.Button
cc.Toggle
cc.ScrollView

负责交互行为。

布局组件

text
cc.Layout
cc.Widget

负责自动调整节点位置和尺寸。

动画组件

text
cc.Animation
sp.Skeleton
dragonBones.ArmatureDisplay

负责动画表现。

自定义脚本组件

你写的业务脚本,例如:

text
LoginPanel
ShopItem
BattleView
RewardItem
StartGameScript

🧠 enabled 和 active 的区别

Component 有自己的开关:

ts
component.enabled = false;

它和 Node 的 active 不一样:

text
node.active = false
关闭整个节点和子树

component.enabled = false
只关闭这个组件

例如:

text
AvatarNode
├── Sprite
├── Button
└── RotateScript

如果:

ts
AvatarNode.active = false;

通常会导致:

text
Sprite 不显示
Button 不响应
RotateScript 不 update
子节点也受影响

如果只是:

ts
RotateScript.enabled = false;

通常是:

text
RotateScript 不工作
Sprite 仍然显示
Button 仍然可以点击
Node 本身仍然 active

🧠 为什么空 update 也有成本?

继承 cc.Component 不代表每帧都会执行。

但只要你写了:

ts
update(dt) {
}

引擎就会认为这个组件需要每帧调度。

即使是空函数,也会有:

text
调度列表记录
每帧遍历
enabled / activeInHierarchy 判断
函数调用

所以:

不用 update,就不要写空 update。


💼 工作中的真实案例

头像还要显示,但不想旋转

错误做法:

ts
AvatarNode.active = false;

这样头像也隐藏了。

正确做法:

ts
this.rotateScript.enabled = false;

只关闭旋转逻辑,头像仍然显示。


⚠️ 常见误区

  • Component 不只是脚本,Sprite、Label、Button 也都是 Component。
  • enabled = false 不等于 node.active = false
  • update() 也有调度成本。
  • 不要把所有逻辑都塞进一个巨大 Component。

🎤 面试会怎么问

Node 和 Component 的关系是什么?

Node 是场景树中的空间对象,负责 Transform、层级、active、事件和组件挂载。Component 是挂在 Node 上的功能模块,负责显示、交互、动画、业务逻辑等具体能力。

enabled 和 active 有什么区别?

active 是 Node 的激活状态,会影响节点及其子树;enabled 是 Component 的开关,只影响当前组件本身。

为什么不建议每个脚本都写 update?

update 每帧都会被引擎调度。大量组件都有 update,会增加调度和函数调用成本。


📝 今日练习参考答案

题目:

text
AvatarNode
├── Sprite
├── Button
└── RotateScript

答案:

  1. AvatarNode 是 Node。
  2. Sprite、Button、RotateScript 都是 Component。
  3. AvatarNode.active = false:头像不显示,按钮不响应,RotateScript 通常不 update。
  4. RotateScript.enabled = false:只关闭旋转逻辑,头像仍然显示,按钮仍然可点。
  5. 头像还要显示但不想旋转,应使用 RotateScript.enabled = false

🚀 能力成长

学完本课后,你应该能:

  • 区分 Node 和 Component
  • 区分 active 和 enabled
  • 判断应该关闭整个节点还是关闭某个组件
  • 清理无意义的空 update
  • 更合理地组织业务逻辑

✅ 本课总结

text
Component 是挂在 Node 上的能力。
Node 决定“在哪里”,Component 决定“做什么”。
node.active = false 影响整个节点和子树。
component.enabled = false 只关闭某个组件。
不用 update,就不要写空 update。

下一课: Node 和 Component 为什么要分开?