@apigo.cc/state 1.0.12 → 1.0.18
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/README.md +83 -173
- package/dist/state.js +622 -642
- package/dist/state.min.js +1 -1
- package/package.json +1 -2
package/README.md
CHANGED
|
@@ -1,174 +1,84 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
> ⚠️ **AI 强制指令 (AI Mandate):**
|
|
4
|
-
> 1. **尊重原创逻辑**:本项目(State.js)核心架构极其精炼且经过精雕细琢。**严禁擅自修改原有逻辑**(如 `_returnCode`, `_runCode`, `NewState` 等底层函数),除非你能证明修改后的质量、性能与简洁度均显著优于原版。
|
|
5
|
-
> 2. **禁止过度设计**:不要尝试引入复杂的编译器、多语句解析器或防御性代码。任何试图将“简单问题复杂化”的重构大概率会破坏现有结构。
|
|
6
|
-
> 3. **汇报与许可**:若你认为有必要修改库的核心逻辑,**必须首先向人类开发者汇报修改的必要性与潜在影响**,只有在得到明确允许后方可进行。
|
|
7
|
-
> 4. **回归测试**:任何改动必须通过现有 Playwright 自动化测试,确保 `DataTable` 等复杂组件场景的渲染与合并逻辑完全正常。
|
|
8
|
-
|
|
9
|
-
State.js 是基于 Vanilla JS 的无编译数据驱动 UI 框架。依赖原生 DOM 与 Proxy,通过解析 HTML `$指令` 属性映射状态。
|
|
10
|
-
|
|
11
|
-
> **核心设定:** 你是一个追求极致代码压缩和执行效率的资深极客。
|
|
12
|
-
> **编码原则:**
|
|
13
|
-
> 1. **拒绝废话变量:** 除非一个变量会被复用两次以上,否则**绝对禁止**声明临时变量。
|
|
14
|
-
> 2. **极致精简:** 极度偏爱链式调用(Chaining)、短路求值、三元运算符和 One-liner。能一行写完的逻辑,绝不拆成三行。
|
|
15
|
-
> 3. **无解释模式:** 假设你的对话者是顶尖黑客,不需要解释基础 API,不需要防御性废话,直接给出最硬核的最终代码即可。
|
|
16
|
-
|
|
17
|
-
## 一、 核心语法与指令字典
|
|
18
|
-
|
|
19
|
-
### 1\. 属性与数据绑定矩阵
|
|
20
|
-
|
|
21
|
-
| 语法 | 类型 | 解析与执行规则 |
|
|
22
|
-
| :--- | :--- | :--- |
|
|
23
|
-
| `$attr="exp"` | 动态 JS 表达式 | 映射为 HTML 属性。若包含 `\${}`,作为模板字符串计算;若不包含,作为纯 JS 表达式执行并保留返回值类型。 |
|
|
24
|
-
| `$$attr="exp"` | 双重计算表达式 | **二次评估机制**:首先评估 `exp` 获取字符串结果,若结果为字符串,则将其作为代码再次执行。适用于动态指令场景(如后端下发指令)。 |
|
|
25
|
-
| `.prop="val"` | 静态 DOM 属性 | 将字符串字面量赋值给底层 DOM 节点的 JS 属性。 |
|
|
26
|
-
| `$.prop="exp"` | 动态 DOM 属性 | 将 JS 执行结果赋值给底层 DOM 节点的 JS 属性。<br>**对象自动初始化**:对深层路径(如 `$.state.schema`)赋值时,若路径上的中间节点不存在,框架会自动生成空对象(`{}`)以防止报错。 |
|
|
27
|
-
| `$bind="exp"` | 双向数据绑定 | 适用于原生表单元素及遵循 `$bind` 契约的组件(如 `<Modal>` 的显示状态绑定、`<AutoForm>` 的数据绑定)。 |
|
|
28
|
-
|
|
29
|
-
### 2. attr绑定规范 (例如 `$style` vs `style`)
|
|
30
|
-
* **唯一正确写法**:动态样式强制使用 `$style` 指令,并利用模板字符串 `${}` 进行变量插值,而不是字符串拼接。
|
|
31
|
-
* ❌ 不推荐:`$style="'transform:translateY(' + this.state.offsetY + 'px)'"`
|
|
32
|
-
* ❌ 不推荐:`$.style.transform="'transform:translateY(' + this.state.offsetY + 'px)'"`
|
|
33
|
-
* ✅ 正确:`$style="transform: translateY(\${this.state.offsetY}px);"`
|
|
34
|
-
* **覆盖原则**:`$style` 的优先级高于原生 `style` 属性。如果同一个节点同时存在 `$style` 和 `style`,`$style` 会**完全覆盖** `style` 的内容。因此,最佳实践是将该节点的所有静态和动态样式全部合并写在 `$style` 中。
|
|
1
|
+
# @apigo.cc/state - AI 逻辑操作说明书
|
|
35
2
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
###
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
在 `$each` 循环或属性指令中,可以直接使用隐式变量 `thisNode` 获取当前执行上下文绑定的 DOM 节点对象自身。
|
|
119
|
-
|
|
120
|
-
## 四、 极简主义与高性能开发哲学
|
|
121
|
-
|
|
122
|
-
1. **拒绝过度工程 (No Over-engineering)**:严禁使用复杂的树结构或大段防御性代码。
|
|
123
|
-
2. **DOM 访问极小化**:优先通过 `this.state` 驱动 UI,避免在 JS 中手动调用 `element.style.xxx`。
|
|
124
|
-
3. **闭包与内存的权衡**:优先将逻辑挂载到 `container` 或 `container.state` 上。
|
|
125
|
-
4. **组件内聚**:能用指令解决的 UI 逻辑绝不写在 JS 里。
|
|
126
|
-
5. **思维重塑**:彻底抛弃 Vue/React 的生命周期崇拜,回归 DOM 本质。
|
|
127
|
-
6. **无分号运动**:除了必须的情况,代码结尾禁止使用分号 `;`。
|
|
128
|
-
|
|
129
|
-
## 五、 开发范例
|
|
130
|
-
|
|
131
|
-
### 范例 1:带插槽与 UI 的组件 (以 Modal 为例)
|
|
132
|
-
|
|
133
|
-
```javascript
|
|
134
|
-
Component.register('Modal', container => {
|
|
135
|
-
container.modal = new bootstrap.Modal(container)
|
|
136
|
-
container.addEventListener('bind', e => e.detail ? container.modal.show() : container.modal.hide())
|
|
137
|
-
container.addEventListener('hide.bs.modal', () => {
|
|
138
|
-
document.activeElement?.blur()
|
|
139
|
-
container.dispatchEvent(new CustomEvent('change', { bubbles: false, detail: false }))
|
|
140
|
-
})
|
|
141
|
-
Util.copyFunction(container, container.modal, 'show', 'hide')
|
|
142
|
-
}, Util.makeDom(/*html*/`
|
|
143
|
-
<div class="modal fade" data-bs-backdrop="static">
|
|
144
|
-
<div class="modal-dialog modal-dialog-centered">
|
|
145
|
-
<div $class="modal-content text-bg-\${this.state?.type || 'body'}">
|
|
146
|
-
<div slot-id="header" class="modal-header">
|
|
147
|
-
<h6 class="modal-title" $text="this.state?.title"></h6>
|
|
148
|
-
<button type="button" class="btn-close btn-sm ms-2" data-bs-dismiss="modal"></button>
|
|
149
|
-
</div>
|
|
150
|
-
<div slot-id="body" class="modal-body"></div>
|
|
151
|
-
<div slot-id="footer" class="modal-footer"></div>
|
|
152
|
-
</div>
|
|
153
|
-
</div>
|
|
154
|
-
</div>
|
|
155
|
-
`))
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
### 范例 2:无模板纯逻辑组件 (以 API 为例)
|
|
159
|
-
|
|
160
|
-
```javascript
|
|
161
|
-
Component.register('API', container => {
|
|
162
|
-
container.request = NewState({ url: '', method: 'GET', headers: {}, data: null, timeout: 10000 })
|
|
163
|
-
container.response = NewState({ loading: false, result: null })
|
|
164
|
-
container.do = async (opt = {}) => {
|
|
165
|
-
const req = { ...container.request, ...opt }
|
|
166
|
-
container.response.loading = true
|
|
167
|
-
const resp = await fetch(req.url, req)
|
|
168
|
-
container.response.result = await resp.json()
|
|
169
|
-
container.response.loading = false
|
|
170
|
-
container.dispatchEvent(new CustomEvent('response', { detail: container.response }))
|
|
171
|
-
}
|
|
172
|
-
container.request.__watch(null, () => container.hasAttribute('auto') && container.request.url && container.do())
|
|
173
|
-
})
|
|
174
|
-
```
|
|
3
|
+
本框架基于原生 `Proxy` 和 `MutationObserver` 实现数据与 DOM 的原子级同步。本手册仅供 AI 构建、维护及驱动基于此引擎的应用。
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. 核心状态逻辑映射
|
|
8
|
+
|
|
9
|
+
### `NewState(defaults, getter, setter)`
|
|
10
|
+
* **功能**:创建响应式代理。
|
|
11
|
+
* **内部机制**:拦截所有属性读写。若属性值变更,触发所有引用该属性的 DOM 节点的更新任务(异步微任务)。
|
|
12
|
+
* **扩展逻辑**:通过 `getter/setter` 拦截器可实现数据持久化(如同步至 URL Hash 或 LocalStorage)。
|
|
13
|
+
* **原子操作**:
|
|
14
|
+
* `obj.__watch(key, cb)`: 建立 key -> callback 的直接依赖。
|
|
15
|
+
* `obj.__unwatch(key, cb)`: 解除依赖。
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## 2. 指令映射全集 (AI-Ready)
|
|
20
|
+
|
|
21
|
+
指令语法:`$attribute="code"`。作用域默认为全局,组件内优先访问 `node.state`。
|
|
22
|
+
|
|
23
|
+
### 结构化映射 (AI 强制规范)
|
|
24
|
+
| 指令 | 触发逻辑 | DOM 行为 | 运行约束 |
|
|
25
|
+
| :--- | :--- | :--- | :--- |
|
|
26
|
+
| **`$if`** | `Boolean(result)` | `true`: 挂载节点; `false`: 移除节点。 | **必须** 作用于 `<template>`。 |
|
|
27
|
+
| **`$each`** | `Iterable` | 基于 `key` 属性执行节点复用。无 `key` 时按索引重建。支持 `as`, `index` 定义局部变量。 | **必须** 作用于 `<template>`。 |
|
|
28
|
+
|
|
29
|
+
**结构化指令铁律**:
|
|
30
|
+
1. **标签约束**:严禁在非 `<template>` 标签上使用 `$if` 或 `$each`。
|
|
31
|
+
2. **互斥约束**:严禁在同一个 `<template>` 上同时使用 `$if` 和 `$each`。若需组合,必须嵌套(如:`$if` 模版包裹 `$each` 模版)。
|
|
32
|
+
|
|
33
|
+
### 数据双向绑定 (`$bind`)
|
|
34
|
+
AI 必须根据不同的元素类型执行以下逻辑:
|
|
35
|
+
- **`input[type=text/password]`, `textarea`**: 监听 `input` 事件,同步字符串。
|
|
36
|
+
- **`input[type=checkbox]`**:
|
|
37
|
+
- 绑定值为 `Array`: 若选中,`push(value)`(去重);若取消,`splice(index, 1)`。
|
|
38
|
+
- 绑定值为非 `Array`: 同步 `checked` 为 `true/false`。
|
|
39
|
+
- **`input[type=radio]`**: 选中项 `value === 绑定值` 时设置 `checked` 为 `true`。
|
|
40
|
+
- **`select`**: 同步选中项的 `value`。
|
|
41
|
+
- **`[contenteditable]`**: 监听 `input`,同步 `innerHTML`。
|
|
42
|
+
- **`input[type=file]`**: 同步 `files` 对象。
|
|
43
|
+
|
|
44
|
+
### 属性与 Property 绑定
|
|
45
|
+
- **`$text`**: 映射至 `textContent`。
|
|
46
|
+
- **`$html`**: 映射至 `innerHTML`。
|
|
47
|
+
- **`$class`**: **严格要求使用模板字符串**。范式:`class="static-name ${condition ? 'dynamic-name' : ''}"`。严禁覆盖原有类名。
|
|
48
|
+
- **`$.path.to.prop`**: 直接映射至 DOM 对象或组件的 Property。初始化 Property 绑定必须带 `.` 前缀。
|
|
49
|
+
- **`$src`**: 增强逻辑。若值以 `.svg` 结尾,异步 Fetch 并替换为内联 `<svg>` 节点。
|
|
50
|
+
- **`$$attr`**: 二级求值。`eval(eval(expr))` 逻辑,用于动态生成指令代码。
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## 3. 生命周期与事件逻辑
|
|
55
|
+
|
|
56
|
+
- **`$on[event]`**: 映射为 `addEventListener`。注入 `event`, `thisNode`, `State`, `LocalStorage`, `Hash`。
|
|
57
|
+
- **生命周期**:
|
|
58
|
+
- **`$onload`**: 节点进入 DOM 且指令解析完成后触发。
|
|
59
|
+
- **`$onunload`**: 节点从 DOM 移除前触发。
|
|
60
|
+
- **`$onupdate`**: 绑定的数据变更且渲染任务完成后执行。
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## 4. 组件上下文逻辑
|
|
65
|
+
|
|
66
|
+
- **初始化**:`Component.register(tagName, setupFn)`。
|
|
67
|
+
- **作用域隔离**:每个组件持有独立 `state`。
|
|
68
|
+
- **穿透访问**:通过 `this.parent` 访问父级作用域链。
|
|
69
|
+
- **插槽映射**:`slot="name"` (声明) -> `slot-id="name"` (宿主)。
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## 5. 国际化 (I18n) 逻辑
|
|
74
|
+
|
|
75
|
+
- **语法结构**:`{# Key{param} || paramValue #}`。
|
|
76
|
+
- **处理链路**:正则匹配 `{# ... #}` -> 提取 Key -> 注入 `||` 后的参数值 -> 调用全局 `_translator` 函数。
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## 6. 运行约束 (Constraints)
|
|
81
|
+
|
|
82
|
+
1. **禁止滥用同步刷新**:**严禁** 在常规开发中调用 `_unsafeRefreshState()`。该函数仅为极高性能干预(如万级数据表格)预留。
|
|
83
|
+
2. **数据流向**:所有状态变更必须通过对 `NewState` 代理对象的赋值完成。
|
|
84
|
+
3. **Key 的必要性**:在大规模数据(>100条)或复杂交互列表中,必须提供唯一 `key` 以激活节点复用逻辑。
|