@love-sqjm/magic 2026.4.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +674 -0
- package/README.md +93 -0
- package/app.js +51 -0
- package/doc/api/examples.md +563 -0
- package/doc/api/index.md +563 -0
- package/doc/architecture.md +322 -0
- package/doc/config-reference.md +646 -0
- package/doc/data-model.md +622 -0
- package/doc/development-guide.md +582 -0
- package/doc/magic-file/index.md +610 -0
- package/doc/user-guide/index.md +485 -0
- package/doc/workflow.md +548 -0
- package/index.js +157 -0
- package/magic.bat +2 -0
- package/magic.ps1 +5 -0
- package/package.json +44 -0
- package/script/build-project.js +16 -0
- package/script/config.js +23 -0
- package/script/create-project.js +73 -0
- package/script/global/printf.js +13 -0
- package/script/global/project-build-config.js +161 -0
- package/script/global/support-platform.js +5 -0
- package/script/module/compiler/global.js +43 -0
- package/script/module/compiler/id-generate.js +18 -0
- package/script/module/compiler/index-dom.js +78 -0
- package/script/module/compiler/macro-replace.js +22 -0
- package/script/module/compiler/macro.js +6 -0
- package/script/module/compiler/start.js +10 -0
- package/script/module/compiler/step/1.js +253 -0
- package/script/module/compiler/step/2.js +79 -0
- package/script/module/compiler/step/3.js +37 -0
- package/script/module/compiler/step/4.js +20 -0
- package/script/module/compiler/step/5.js +634 -0
- package/script/module/compiler/step/6.js +304 -0
- package/script/module/compiler/step/end.js +124 -0
- package/script/run-project.js +249 -0
- package/script/util/bun-fs.js +40 -0
- package/script/util/copy-dir.js +21 -0
- package/script/util/create-simple-dom-element.js +23 -0
- package/script/util/file-util.js +95 -0
- package/script/util/filtration-file.js +20 -0
- package/script/util/get-dir-all-file.js +28 -0
- package/script/util/get-first-object-key.js +9 -0
- package/script/util/is-empty-object.js +8 -0
- package/script/util/is-string-over-size.js +4 -0
- package/script/util/is.js +18 -0
- package/script/util/logging.js +142 -0
- package/script/util/task.js +16 -0
- package/script/util/traversal.js +28 -0
- package/template/platform-config/node-webkit +23 -0
- package/template/platform-config/web +1 -0
- package/template/project-base/app.xml +5 -0
- package/template/project-base/build.module.toml +37 -0
- package/template/project-base/build.toml +43 -0
- package/template/runtime/runtime.css +3 -0
- package/template/runtime/runtime.js +895 -0
|
@@ -0,0 +1,582 @@
|
|
|
1
|
+
# Magic 开发规范
|
|
2
|
+
|
|
3
|
+
## 目录
|
|
4
|
+
|
|
5
|
+
1. [编码标准](#1-编码标准)
|
|
6
|
+
2. [命名约定](#2-命名约定)
|
|
7
|
+
3. [文件组织](#3-文件组织)
|
|
8
|
+
4. [组件开发规范](#4-组件开发规范)
|
|
9
|
+
5. [CSS 规范](#5-css-规范)
|
|
10
|
+
6. [事件处理规范](#6-事件处理规范)
|
|
11
|
+
7. [接口设计规范](#7-接口设计规范)
|
|
12
|
+
8. [文档规范](#8-文档规范)
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## 1. 编码标准
|
|
17
|
+
|
|
18
|
+
### 1.1 基本原则
|
|
19
|
+
|
|
20
|
+
- 使用 UTF-8 编码
|
|
21
|
+
- 使用 Tab 缩进(2-4 个 Tab)
|
|
22
|
+
- 每行不超过 120 个字符
|
|
23
|
+
- 关键字后加空格:`if (condition)`
|
|
24
|
+
- 函数调用不加空格:`func(arg)`
|
|
25
|
+
|
|
26
|
+
### 1.2 字符串
|
|
27
|
+
|
|
28
|
+
- 优先使用单引号
|
|
29
|
+
- 模板字符串用于多行或变量插值
|
|
30
|
+
|
|
31
|
+
```javascript
|
|
32
|
+
// 推荐
|
|
33
|
+
const name = 'Magic';
|
|
34
|
+
const message = `Hello, ${name}!`;
|
|
35
|
+
|
|
36
|
+
// 避免
|
|
37
|
+
const name = "Magic";
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### 1.3 变量声明
|
|
41
|
+
|
|
42
|
+
- 使用 `const` 优先于 `let`
|
|
43
|
+
- 避免使用 `var`
|
|
44
|
+
- 命名清晰的变量名
|
|
45
|
+
|
|
46
|
+
```javascript
|
|
47
|
+
// 推荐
|
|
48
|
+
const maxRetries = 3;
|
|
49
|
+
const userList = [];
|
|
50
|
+
|
|
51
|
+
// 避免
|
|
52
|
+
const a = 3;
|
|
53
|
+
const list = [];
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### 1.4 函数
|
|
57
|
+
|
|
58
|
+
```javascript
|
|
59
|
+
// 箭头函数
|
|
60
|
+
const add = (a, b) => a + b;
|
|
61
|
+
|
|
62
|
+
// 普通函数
|
|
63
|
+
function multiply(a, b) {
|
|
64
|
+
return a * b;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// 异步函数
|
|
68
|
+
async function fetchData(url) {
|
|
69
|
+
const response = await fetch(url);
|
|
70
|
+
return response.json();
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### 1.5 对象和数组
|
|
75
|
+
|
|
76
|
+
```javascript
|
|
77
|
+
// 对象
|
|
78
|
+
const config = {
|
|
79
|
+
name: 'my-app',
|
|
80
|
+
version: '1.0.0',
|
|
81
|
+
getData() {
|
|
82
|
+
return this.name;
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
// 数组
|
|
87
|
+
const items = [1, 2, 3];
|
|
88
|
+
const newItems = items.map(item => item * 2);
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## 2. 命名约定
|
|
94
|
+
|
|
95
|
+
### 2.1 文件命名
|
|
96
|
+
|
|
97
|
+
| 类型 | 规范 | 示例 |
|
|
98
|
+
|------|------|------|
|
|
99
|
+
| .m 组件 | kebab-case | `greeting-card.m`, `user-profile.m` |
|
|
100
|
+
| JavaScript | camelCase | `util.js`, `api-handler.js` |
|
|
101
|
+
| CSS | kebab-case | `theme.css`, `button-styles.css` |
|
|
102
|
+
| 图片 | kebab-case | `logo-small.png`, `bg-pattern.jpg` |
|
|
103
|
+
|
|
104
|
+
### 2.2 元素 ID 命名
|
|
105
|
+
|
|
106
|
+
```xml
|
|
107
|
+
<!-- 推荐:描述性名称 -->
|
|
108
|
+
<div #id="header-container">...</div>
|
|
109
|
+
<div #id="user-name-label">...</div>
|
|
110
|
+
|
|
111
|
+
<!-- 避免:无意义名称 -->
|
|
112
|
+
<div #id="div1">...</div>
|
|
113
|
+
<div #id="d1">...</div>
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
**命名模式:**
|
|
117
|
+
- `$id="元素类型-功能"` 如 `$id="main-content"`
|
|
118
|
+
- `$id="元素类型-序号"` 如 `$id="list-item-1"`
|
|
119
|
+
|
|
120
|
+
### 2.3 变量命名
|
|
121
|
+
|
|
122
|
+
| 类型 | 规范 | 示例 |
|
|
123
|
+
|------|------|------|
|
|
124
|
+
| 普通变量 | camelCase | `userName`, `isValid` |
|
|
125
|
+
| 常量 | UPPER_SNAKE | `MAX_COUNT`, `API_URL` |
|
|
126
|
+
| 布尔值 | is/has/can 前缀 | `isVisible`, `hasChildren` |
|
|
127
|
+
| 数组 | 复数名词 | `users`, `itemList` |
|
|
128
|
+
| DOM 元素 | `$` 前缀 | `$button`, `$container` |
|
|
129
|
+
|
|
130
|
+
### 2.4 函数命名
|
|
131
|
+
|
|
132
|
+
| 类型 | 规范 | 示例 |
|
|
133
|
+
|------|------|------|
|
|
134
|
+
| 事件处理 | `on` + 事件名 | `onClick`, `onChange` |
|
|
135
|
+
| 事件定义 | 动词 | `handleClick`, `processSubmit` |
|
|
136
|
+
| 回调 | `callback` | `onCompleteCallback` |
|
|
137
|
+
| 获取数据 | `get` + 名词 | `getUserData`, `fetchConfig` |
|
|
138
|
+
| 设置数据 | `set` + 名词 | `setUserName`, `updateConfig` |
|
|
139
|
+
| 判断 | `is`/`has`/`can` + 名词 | `isValid`, `hasPermission` |
|
|
140
|
+
|
|
141
|
+
### 2.5 CSS 类名
|
|
142
|
+
|
|
143
|
+
```css
|
|
144
|
+
/* BEM 风格 */
|
|
145
|
+
.button { }
|
|
146
|
+
.button__icon { }
|
|
147
|
+
.button--disabled { }
|
|
148
|
+
|
|
149
|
+
/* 组件作用域 */
|
|
150
|
+
.m-css-scope-xxx { }
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## 3. 文件组织
|
|
156
|
+
|
|
157
|
+
### 3.1 目录结构
|
|
158
|
+
|
|
159
|
+
```
|
|
160
|
+
app/
|
|
161
|
+
├── app.xml # 应用配置(必需)
|
|
162
|
+
├── index.m # 入口模块(必需)
|
|
163
|
+
├── components/ # 可复用组件
|
|
164
|
+
│ ├── button/
|
|
165
|
+
│ │ └── button.m
|
|
166
|
+
│ ├── dialog/
|
|
167
|
+
│ │ └── dialog.m
|
|
168
|
+
│ └── card/
|
|
169
|
+
│ └── card.m
|
|
170
|
+
├── pages/ # 页面组件
|
|
171
|
+
│ ├── home/
|
|
172
|
+
│ │ └── index.m
|
|
173
|
+
│ └── about/
|
|
174
|
+
│ └── index.m
|
|
175
|
+
├── layouts/ # 布局组件
|
|
176
|
+
│ └── main-layout.m
|
|
177
|
+
├── shared/ # 共享模块
|
|
178
|
+
│ ├── header.m
|
|
179
|
+
│ └── footer.m
|
|
180
|
+
└── assets/ # 静态资源
|
|
181
|
+
├── images/
|
|
182
|
+
├── fonts/
|
|
183
|
+
└── data/
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### 3.2 导入组织
|
|
187
|
+
|
|
188
|
+
```xml
|
|
189
|
+
<!-- 1. 导入外部库(如有) -->
|
|
190
|
+
<!-- 2. 导入共享组件 -->
|
|
191
|
+
<!-- 3. 导入页面组件 -->
|
|
192
|
+
|
|
193
|
+
<import root=".">
|
|
194
|
+
<!-- 共享组件 -->
|
|
195
|
+
<header/>
|
|
196
|
+
<footer/>
|
|
197
|
+
|
|
198
|
+
<!-- 页面组件 -->
|
|
199
|
+
<home/>
|
|
200
|
+
</import>
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
---
|
|
204
|
+
|
|
205
|
+
## 4. 组件开发规范
|
|
206
|
+
|
|
207
|
+
### 4.1 .m 文件结构顺序
|
|
208
|
+
|
|
209
|
+
```xml
|
|
210
|
+
<import> <!-- 1. 导入(可选) -->
|
|
211
|
+
<template> <!-- 2. 模板(必需) -->
|
|
212
|
+
<script code=""> <!-- 3. 脚本(可选,多个) -->
|
|
213
|
+
<css> <!-- 4. 样式(可选,多个) -->
|
|
214
|
+
<expose-event> <!-- 5. 事件暴露(可选) -->
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### 4.2 模板规范
|
|
218
|
+
|
|
219
|
+
```xml
|
|
220
|
+
<template>
|
|
221
|
+
<!-- 根元素必须有 #id -->
|
|
222
|
+
<div #id="组件根元素">
|
|
223
|
+
<!-- 子元素使用有意义的 #id -->
|
|
224
|
+
<header #id="组件头部">
|
|
225
|
+
<h1 #id="标题">Title</h1>
|
|
226
|
+
</header>
|
|
227
|
+
<main #id="内容区域">
|
|
228
|
+
<!-- 组件内容 -->
|
|
229
|
+
</main>
|
|
230
|
+
<footer #id="组件底部">
|
|
231
|
+
</footer>
|
|
232
|
+
</div>
|
|
233
|
+
</template>
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
### 4.3 脚本规范
|
|
237
|
+
|
|
238
|
+
#### 全局脚本 (code="global")
|
|
239
|
+
|
|
240
|
+
```xml
|
|
241
|
+
<script code="global">
|
|
242
|
+
// 1. 获取元素
|
|
243
|
+
const {
|
|
244
|
+
$root,
|
|
245
|
+
$header,
|
|
246
|
+
$content
|
|
247
|
+
} = $id();
|
|
248
|
+
|
|
249
|
+
// 2. 定义组件状态
|
|
250
|
+
const state = {
|
|
251
|
+
isExpanded: false
|
|
252
|
+
};
|
|
253
|
+
</script>
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
#### 事件脚本 (code="event")
|
|
257
|
+
|
|
258
|
+
```xml
|
|
259
|
+
<script code="event">
|
|
260
|
+
// 事件处理函数定义
|
|
261
|
+
clickHandler = (event) => {
|
|
262
|
+
// 处理点击
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
submitForm = (data) => {
|
|
266
|
+
// 处理表单提交
|
|
267
|
+
}
|
|
268
|
+
</script>
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
#### 接口脚本 (code="interface")
|
|
272
|
+
|
|
273
|
+
```xml
|
|
274
|
+
<script code="interface">
|
|
275
|
+
// 对外暴露的方法
|
|
276
|
+
setTitle = (title) => {
|
|
277
|
+
$header.textContent = title;
|
|
278
|
+
};
|
|
279
|
+
|
|
280
|
+
getData = () => {
|
|
281
|
+
return state;
|
|
282
|
+
};
|
|
283
|
+
</script>
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
### 4.4 组件接口设计
|
|
287
|
+
|
|
288
|
+
```xml
|
|
289
|
+
<!-- 组件 -->
|
|
290
|
+
<script code="interface">
|
|
291
|
+
// 数据设置
|
|
292
|
+
setData = (data) => {
|
|
293
|
+
// 设置组件数据
|
|
294
|
+
};
|
|
295
|
+
|
|
296
|
+
// 状态控制
|
|
297
|
+
enable = () => {};
|
|
298
|
+
disable = () => {};
|
|
299
|
+
|
|
300
|
+
// 事件触发
|
|
301
|
+
show = () => {};
|
|
302
|
+
hide = () => {};
|
|
303
|
+
|
|
304
|
+
// 数据获取
|
|
305
|
+
getValue = () => {};
|
|
306
|
+
</script>
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
---
|
|
310
|
+
|
|
311
|
+
## 5. CSS 规范
|
|
312
|
+
|
|
313
|
+
### 5.1 作用域使用
|
|
314
|
+
|
|
315
|
+
```xml
|
|
316
|
+
<!-- 正确:使用 #id:xx 作用域 -->
|
|
317
|
+
<css scope="#id:my-component">
|
|
318
|
+
& {
|
|
319
|
+
/* 组件样式 */
|
|
320
|
+
}
|
|
321
|
+
</css>
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
### 5.2 样式分离
|
|
325
|
+
|
|
326
|
+
```xml
|
|
327
|
+
<!-- 主题样式(带 default-theme) -->
|
|
328
|
+
<css scope="#id:button" default-theme>
|
|
329
|
+
& {
|
|
330
|
+
background-color: #007bff;
|
|
331
|
+
color: #ffffff;
|
|
332
|
+
}
|
|
333
|
+
</css>
|
|
334
|
+
|
|
335
|
+
<!-- 布局样式 -->
|
|
336
|
+
<css scope="#id:button">
|
|
337
|
+
& {
|
|
338
|
+
display: inline-flex;
|
|
339
|
+
padding: 8px 16px;
|
|
340
|
+
border-radius: 4px;
|
|
341
|
+
}
|
|
342
|
+
</css>
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
### 5.3 嵌套规则
|
|
346
|
+
|
|
347
|
+
```xml
|
|
348
|
+
<css scope="#id:card">
|
|
349
|
+
& {
|
|
350
|
+
/* 根样式 */
|
|
351
|
+
}
|
|
352
|
+
& > .header {
|
|
353
|
+
/* 直接子元素 */
|
|
354
|
+
}
|
|
355
|
+
& .content {
|
|
356
|
+
/* 后代元素 */
|
|
357
|
+
}
|
|
358
|
+
&:hover {
|
|
359
|
+
/* 伪类 */
|
|
360
|
+
}
|
|
361
|
+
</css>
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
### 5.4 避免样式冲突
|
|
365
|
+
|
|
366
|
+
- 不使用全局样式
|
|
367
|
+
- 所有样式都在作用域内
|
|
368
|
+
- 使用 `#id:xx` 而非直接使用元素名
|
|
369
|
+
|
|
370
|
+
```xml
|
|
371
|
+
<!-- 避免 -->
|
|
372
|
+
<css>
|
|
373
|
+
div { color: red; }
|
|
374
|
+
</css>
|
|
375
|
+
|
|
376
|
+
<!-- 推荐 -->
|
|
377
|
+
<css scope="#id:container">
|
|
378
|
+
& div { color: red; }
|
|
379
|
+
</css>
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
---
|
|
383
|
+
|
|
384
|
+
## 6. 事件处理规范
|
|
385
|
+
|
|
386
|
+
### 6.1 事件命名
|
|
387
|
+
|
|
388
|
+
使用小驼峰命名:
|
|
389
|
+
|
|
390
|
+
| 事件 | 说明 |
|
|
391
|
+
|------|------|
|
|
392
|
+
| `click` | 点击 |
|
|
393
|
+
| `change` | 值改变 |
|
|
394
|
+
| `select` | 选中 |
|
|
395
|
+
| `open` | 打开 |
|
|
396
|
+
| `close` | 关闭 |
|
|
397
|
+
| `submit` | 提交 |
|
|
398
|
+
| `cancel` | 取消 |
|
|
399
|
+
|
|
400
|
+
### 6.2 expose-event 定义
|
|
401
|
+
|
|
402
|
+
```xml
|
|
403
|
+
<expose-event>
|
|
404
|
+
<!-- 基本事件 -->
|
|
405
|
+
<click/>
|
|
406
|
+
<change/>
|
|
407
|
+
|
|
408
|
+
<!-- 带参数事件 -->
|
|
409
|
+
<select :value/>
|
|
410
|
+
<action :type :data/>
|
|
411
|
+
</expose-event>
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
### 6.3 事件触发
|
|
415
|
+
|
|
416
|
+
```xml
|
|
417
|
+
<script code="event">
|
|
418
|
+
click = (event) => {
|
|
419
|
+
emit_event("click", event);
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
select = (value) => {
|
|
423
|
+
emit_event("select", { value });
|
|
424
|
+
}
|
|
425
|
+
</script>
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
### 6.4 事件监听
|
|
429
|
+
|
|
430
|
+
```xml
|
|
431
|
+
<template>
|
|
432
|
+
<!-- 监听子组件事件 -->
|
|
433
|
+
<my-component
|
|
434
|
+
#listen:click="onChildClick"
|
|
435
|
+
#listen:select="onChildSelect"
|
|
436
|
+
/>
|
|
437
|
+
</template>
|
|
438
|
+
|
|
439
|
+
<script code="listen">
|
|
440
|
+
onChildClick = (event) => {
|
|
441
|
+
console.log("Child clicked:", event);
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
onChildSelect = (data) => {
|
|
445
|
+
console.log("Child selected:", data);
|
|
446
|
+
}
|
|
447
|
+
</script>
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
---
|
|
451
|
+
|
|
452
|
+
## 7. 接口设计规范
|
|
453
|
+
|
|
454
|
+
### 7.1 接口命名
|
|
455
|
+
|
|
456
|
+
```xml
|
|
457
|
+
<script code="interface">
|
|
458
|
+
// 设置方法
|
|
459
|
+
setData = (data) => {};
|
|
460
|
+
setTitle = (title) => {};
|
|
461
|
+
setOptions = (options) => {};
|
|
462
|
+
|
|
463
|
+
// 获取方法
|
|
464
|
+
getData = () => {};
|
|
465
|
+
getValue = () => {};
|
|
466
|
+
|
|
467
|
+
// 状态方法
|
|
468
|
+
show = () => {};
|
|
469
|
+
hide = () => {};
|
|
470
|
+
enable = () => {};
|
|
471
|
+
disable = () => {};
|
|
472
|
+
|
|
473
|
+
// 动作方法
|
|
474
|
+
refresh = () => {};
|
|
475
|
+
reset = () => {};
|
|
476
|
+
submit = () => {};
|
|
477
|
+
</script>
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
### 7.2 once 接口
|
|
481
|
+
|
|
482
|
+
`once` 标记的接口在模块初始化时只执行一次:
|
|
483
|
+
|
|
484
|
+
```xml
|
|
485
|
+
<script code="interface" once>
|
|
486
|
+
initialize = () => {
|
|
487
|
+
// 只执行一次
|
|
488
|
+
};
|
|
489
|
+
</script>
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
### 7.3 接口参数设计
|
|
493
|
+
|
|
494
|
+
```xml
|
|
495
|
+
<script code="interface">
|
|
496
|
+
// 简单参数
|
|
497
|
+
setTitle = (title) => {};
|
|
498
|
+
|
|
499
|
+
// 对象参数(推荐用于多参数)
|
|
500
|
+
setConfig = (config) => {
|
|
501
|
+
if (config.width) { /* ... */ }
|
|
502
|
+
if (config.height) { /* ... */ }
|
|
503
|
+
};
|
|
504
|
+
|
|
505
|
+
// 回调参数
|
|
506
|
+
load = (onComplete, onError) => {
|
|
507
|
+
// ...
|
|
508
|
+
};
|
|
509
|
+
</script>
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
---
|
|
513
|
+
|
|
514
|
+
## 8. 文档规范
|
|
515
|
+
|
|
516
|
+
### 8.1 .m 文件注释
|
|
517
|
+
|
|
518
|
+
```xml
|
|
519
|
+
<!--
|
|
520
|
+
* Button 组件
|
|
521
|
+
* 用于触发操作
|
|
522
|
+
*
|
|
523
|
+
* @param {string} text - 按钮文本
|
|
524
|
+
* @param {boolean} disabled - 是否禁用
|
|
525
|
+
* @fires click
|
|
526
|
+
-->
|
|
527
|
+
<template>
|
|
528
|
+
<button #id="btn">按钮</button>
|
|
529
|
+
</template>
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
### 8.2 脚本注释
|
|
533
|
+
|
|
534
|
+
```javascript
|
|
535
|
+
/**
|
|
536
|
+
* 处理按钮点击事件
|
|
537
|
+
* @param {Event} event - 原生事件对象
|
|
538
|
+
*/
|
|
539
|
+
clickHandler = (event) => {
|
|
540
|
+
// ...
|
|
541
|
+
};
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
### 8.3 示例注释
|
|
545
|
+
|
|
546
|
+
```xml
|
|
547
|
+
<!-- 示例:基本用法 -->
|
|
548
|
+
<!--
|
|
549
|
+
<import root=".">
|
|
550
|
+
<my-button/>
|
|
551
|
+
</import>
|
|
552
|
+
|
|
553
|
+
<script>
|
|
554
|
+
// 使用
|
|
555
|
+
const btn = magic.importM("my-button");
|
|
556
|
+
btn.interface.setText("点击我");
|
|
557
|
+
</script>
|
|
558
|
+
-->
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
---
|
|
562
|
+
|
|
563
|
+
## 最佳实践总结
|
|
564
|
+
|
|
565
|
+
### DO
|
|
566
|
+
|
|
567
|
+
1. **使用有意义的命名**
|
|
568
|
+
2. **保持组件职责单一**
|
|
569
|
+
3. **合理拆分大型组件**
|
|
570
|
+
4. **使用 `const` 避免意外修改**
|
|
571
|
+
5. **事件处理函数抽离**
|
|
572
|
+
6. **样式使用作用域隔离**
|
|
573
|
+
7. **提供清晰的接口文档**
|
|
574
|
+
|
|
575
|
+
### DON'T
|
|
576
|
+
|
|
577
|
+
1. **避免全局变量污染**
|
|
578
|
+
2. **避免巨型单一组件**
|
|
579
|
+
3. **避免硬编码值**
|
|
580
|
+
4. **避免样式冲突**
|
|
581
|
+
5. **避免不必要的事件冒泡**
|
|
582
|
+
6. **避免裸露的内部实现**
|