@lark.js/mvc 0.0.2 → 0.0.3
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 +25 -25
- package/dist/{chunk-5OEHRF3U.js → chunk-Y72BUONO.js} +8 -9
- package/dist/index.cjs +165 -54
- package/dist/index.d.cts +79 -19
- package/dist/index.d.ts +79 -19
- package/dist/index.js +163 -51
- package/dist/vite.cjs +8 -9
- package/dist/vite.d.cts +1 -1
- package/dist/vite.d.ts +1 -1
- package/dist/vite.js +1 -1
- package/dist/webpack.cjs +8 -9
- package/dist/webpack.js +1 -1
- package/package.json +9 -6
- package/lark.d.ts +0 -1176
package/README.md
CHANGED
|
@@ -116,7 +116,7 @@ creator 函数接收两个参数: store 是 Proxy 代理对象, 可以读写 sta
|
|
|
116
116
|
|
|
117
117
|
View.extend(props) 创建视图子类, 模板属性 template 引用编译后的 HTML 模板函数, init 方法中通过 useStore(this) 获取 store 实例并绑定视图生命周期, store.observe(this, keys) 声明观察的状态键
|
|
118
118
|
|
|
119
|
-
事件方法的方法名格式为 name<eventType>, 例如 increment<click> 对应模板中的
|
|
119
|
+
事件方法的方法名格式为 name<eventType>, 例如 increment<click> 对应模板中的 @click="increment()", 编译时自动编码 View ID, 运行时由 EventDelegator 解析分发
|
|
120
120
|
|
|
121
121
|
```typescript
|
|
122
122
|
import { Router } from "@lark.js/mvc";
|
|
@@ -155,15 +155,15 @@ export default View.extend({
|
|
|
155
155
|
|
|
156
156
|
4. 创建模板
|
|
157
157
|
|
|
158
|
-
模板使用 {{}} 语法, = 表示 HTML 转义输出,
|
|
158
|
+
模板使用 {{}} 语法, = 表示 HTML 转义输出, @click 等属性绑定事件, 编译时自动将 View ID 和参数编码到事件属性值中
|
|
159
159
|
|
|
160
160
|
```html
|
|
161
161
|
<div>
|
|
162
162
|
<div>{{=count}}</div>
|
|
163
|
-
<input type="number" value="{{=step}}"
|
|
164
|
-
<button
|
|
165
|
-
<button
|
|
166
|
-
<button
|
|
163
|
+
<input type="number" value="{{=step}}" @change="stepChange()" />
|
|
164
|
+
<button @click="decrement()">-{{=step}}</button>
|
|
165
|
+
<button @click="reset()">Reset</button>
|
|
166
|
+
<button @click="increment()">+{{=step}}</button>
|
|
167
167
|
|
|
168
168
|
{{if history.length > 0}}
|
|
169
169
|
<ul>
|
|
@@ -491,8 +491,8 @@ const frame = {
|
|
|
491
491
|
|
|
492
492
|
// 子 frameId 映射
|
|
493
493
|
childrenMap: {
|
|
494
|
-
frame_0: "frame_0", // 对应 lark
|
|
495
|
-
frame_1: "frame_1", // 对应 lark
|
|
494
|
+
frame_0: "frame_0", // 对应 v-lark="components/counter-store"
|
|
495
|
+
frame_1: "frame_1", // 对应 v-lark="components/counter-updater"
|
|
496
496
|
},
|
|
497
497
|
|
|
498
498
|
// readyMap 已 ready 的子 frame 集合
|
|
@@ -509,7 +509,7 @@ const frame = {
|
|
|
509
509
|
- `unmountView()`: 销毁 View 以及所有子 Frame, 清理事件绑定与资源
|
|
510
510
|
- `mountFrame(frameId, viewPath, viewInitParams?)`: 挂载子 Frame, 复用对象池中的 Frame 或创建新 Frame
|
|
511
511
|
- `unmountFrame(id?)`: 卸载子 Frame, 归还 Frame 对象到对象池
|
|
512
|
-
- `mountZone(zoneId?)` / `unmountZone(zoneId?)`: 管理区域内的 lark
|
|
512
|
+
- `mountZone(zoneId?)` / `unmountZone(zoneId?)`: 管理区域内的 v-lark 子视图, 区域内的子 Frame 在 mountZone 时批量创建
|
|
513
513
|
- `invoke(name, args?)`: 沿 Frame 树广播方法调用; 如果 View 已渲染则直接调用, 否则加入 invokeList 延迟执行
|
|
514
514
|
- `children()`: 返回所有子 Frame ID 列表
|
|
515
515
|
- `parent(level?)`: 获取指定层级的父 Frame
|
|
@@ -553,7 +553,7 @@ _视图继承_
|
|
|
553
553
|
|
|
554
554
|
```html
|
|
555
555
|
<button class="btn">只需要写 CSS 类名</button>
|
|
556
|
-
<div class="tooltip">不需要写
|
|
556
|
+
<div class="tooltip">不需要写 @event, 适用于批量绑定</div>
|
|
557
557
|
```
|
|
558
558
|
|
|
559
559
|
事件委托 (viewDelegateEvents): 将 View 的 eventObjectMap 和 eventSelectorMap 注册到 EventDelegator, 全局事件类型 (如 click, change) 绑定到 document.body, 选择器事件通过 matches() API 匹配; 同时处理 window/document 前缀的全局事件 (例如 resize, scroll), 绑定到 window/document
|
|
@@ -601,7 +601,7 @@ Updater — 数据绑定与 VDOM diff
|
|
|
601
601
|
- 执行 VDOM diff (vdomSetChildNodes) 实际上是真实 DOM diff, 计算最小 DOM 操作集
|
|
602
602
|
- 调用 `applyIdUpdates()` 批量更新元素 ID
|
|
603
603
|
- 调用 `applyVdomOps()` 批量执行 DOM 操作
|
|
604
|
-
- 通知 Frame 处理新增的 lark
|
|
604
|
+
- 通知 Frame 处理新增的 v-lark 子视图 (mountZone)
|
|
605
605
|
3. `updater.snapshot()`: 保存当前数据的 JSON 快照
|
|
606
606
|
4. `updater.altered()`: 检测数据是否与上次快照不同 (通过 JSON.stringify 比较)
|
|
607
607
|
5. `updater.get(key?)`: 获取数据, 不传递 key 则返回完整数据对象
|
|
@@ -618,14 +618,14 @@ VDOM Diff Engine — 虚拟 DOM (实际上是真实 DOM) 差量比较引擎
|
|
|
618
618
|
|
|
619
619
|
核心算法:
|
|
620
620
|
|
|
621
|
-
- `vdomSetNode(oldNode, newNode, parent, ref, frame, keys?)`: 对比单个节点. 先执行 vdomSpecialDiff 处理表单元素, 再通过 isEqualNode 判断节点是否相同. 如果节点类型和名称相同, 则分别对比属性 (vdomSetAttributes) 和子节点 (vdomSetChildNodes); 如果节点类型不同, 则生成 replaceChild 操作. 对于有 lark
|
|
622
|
-
- `vdomSetChildNodes(oldParent, newParent, ref, frame, keys?)`: 对比子节点列表, 支持 keyed diff. 算法: 先从旧子节点构建 keyedNodes 映射 (键由 vdomGetCompareKey 获取, 优先级 id >
|
|
621
|
+
- `vdomSetNode(oldNode, newNode, parent, ref, frame, keys?)`: 对比单个节点. 先执行 vdomSpecialDiff 处理表单元素, 再通过 isEqualNode 判断节点是否相同. 如果节点类型和名称相同, 则分别对比属性 (vdomSetAttributes) 和子节点 (vdomSetChildNodes); 如果节点类型不同, 则生成 replaceChild 操作. 对于有 v-lark 属性的元素, 如果新旧 view 路径相同则跳过子节点更新, 保护已挂载的子视图
|
|
622
|
+
- `vdomSetChildNodes(oldParent, newParent, ref, frame, keys?)`: 对比子节点列表, 支持 keyed diff. 算法: 先从旧子节点构建 keyedNodes 映射 (键由 vdomGetCompareKey 获取, 优先级 id > ldk > v-lark 路径), 同时统计新子节点的 keyed 计数; 再遍历新子节点, 通过 keyed 匹配查找旧节点, 匹配成功则将旧节点移动到正确位置并递归 diff, 匹配失败则生成 appendChild 操作; 最后移除多余的旧节点
|
|
623
623
|
- `vdomSetAttributes(oldNode, newNode, ref, keepId?)`: 对比元素属性. 删除新节点中不存在的旧属性, 添加/更新新节点中的属性. id 属性变更记录到 idUpdates 数组而不是直接修改, 因为 id 变更可能影响事件委托. 每次对比前清除 compareKeyCached 缓存
|
|
624
624
|
- `vdomSpecialDiff(oldNode, newNode)`: 处理 input (value, checked), textarea (value), option (selected) 等特殊元素, 直接同步 DOM 属性值, 绕过 setAttribute
|
|
625
625
|
|
|
626
|
-
比较键 (vdomGetCompareKey): 用于 keyed diff 的节点标识, 优先级: id 属性 >
|
|
626
|
+
比较键 (vdomGetCompareKey): 用于 keyed diff 的节点标识, 优先级: id 属性 > ldk 属性 > v-lark 路径. 有 autoId 标记的元素不使用 id 作为比较键. 比较键结果缓存到元素的 compareKeyCached / cachedCompareKey 属性
|
|
627
627
|
|
|
628
|
-
静态跳过: 有
|
|
628
|
+
静态跳过: 有 ldk 属性且值相同的元素跳过 diff; 有 lak 属性且值相同的元素跳过属性更新
|
|
629
629
|
|
|
630
630
|
DOM 操作编码为数字操作码:
|
|
631
631
|
|
|
@@ -642,12 +642,12 @@ HTML 解析: `vdomGetNode(html, refNode)` 使用 `document.implementation.create
|
|
|
642
642
|
|
|
643
643
|
EventDelegator — DOM 事件委托
|
|
644
644
|
|
|
645
|
-
所有 DOM 事件委托到 document.body, 通过事件冒泡机制捕获. 每个 View 的
|
|
645
|
+
所有 DOM 事件委托到 document.body, 通过事件冒泡机制捕获. 每个 View 的 @event 属性在编译时编码为 viewId\x1ehandlerName(params) 格式, 运行时由 EventDelegator 解析并分发
|
|
646
646
|
|
|
647
647
|
核心机制:
|
|
648
648
|
|
|
649
649
|
- `bind(eventType, selector?)`: 注册事件类型到 document.body, 选择器事件使用事件委托匹配; 同一事件类型只注册一次全局监听器
|
|
650
|
-
- `domEventProcessor(event)`: 事件处理入口, 从目标元素向上遍历 DOM 树查找
|
|
650
|
+
- `domEventProcessor(event)`: 事件处理入口, 从目标元素向上遍历 DOM 树查找 @event 属性, 解析得到 View ID 与处理器名称; 解析使用 EVENT_METHOD_REGEX 正则, 捕获 Frame ID (可选), handler 名称, 参数字符串
|
|
651
651
|
- `findFrameInfo(element)`: View 边界检测, 从目标元素向上查找, 当遇到已绑定的 Frame 元素时停止, 确保事件不会跨 View 传播. 通过 rangeFrameId 属性标记 View 边界, 事件冒泡到边界时停止搜索
|
|
652
652
|
- `clearRangeEvents(frameId)`: 清除指定 View 范围内的事件标记
|
|
653
653
|
|
|
@@ -655,7 +655,7 @@ EventDelegator — DOM 事件委托
|
|
|
655
655
|
|
|
656
656
|
选择器事件: 方法名中 $ 前缀标识选择器事件 (例如 `$menu<hover>`), 编译时将选择器名称编码到 eventSelectorMap, 运行时通过 `element.matches(selector)` API 匹配, 支持 CSS 选择器语法
|
|
657
657
|
|
|
658
|
-
Range 事件: 通过
|
|
658
|
+
Range 事件: 通过 lvk 属性标记 View 边界, 事件处理时检查 rangeFrameId, 确保只在对应 View 的 DOM 范围内查找事件处理器
|
|
659
659
|
|
|
660
660
|
Service + Bag — 接口请求管理
|
|
661
661
|
|
|
@@ -688,7 +688,7 @@ Compiler — 模板编译器
|
|
|
688
688
|
第一阶段 — 预处理:
|
|
689
689
|
|
|
690
690
|
- protectComments(): 保护 HTML 注释内的模板语法不被误处理; 将注释替换为 **lark_comment_N** 占位符, 编译完成后恢复
|
|
691
|
-
- processViewEvents(): 处理
|
|
691
|
+
- processViewEvents(): 处理 @event 属性, 添加 \x1f (VIEW_ID_PLACEHOLDER) 前缀 + \x1e (SPLITTER) 分隔符, 将 JS 对象字面量参数转换为 URL 查询参数格式. 例如: @click="handlerName({key: 'value'})" 转换为 @click="\x1f\x1ehandlerName(key=value)"
|
|
692
692
|
|
|
693
693
|
第二阶段 — 语法转换:
|
|
694
694
|
|
|
@@ -800,7 +800,7 @@ updater.digest()
|
|
|
800
800
|
│ └── 特殊元素 → 直接同步 value / checked / selected
|
|
801
801
|
├── applyIdUpdates() — 批量更新元素 ID
|
|
802
802
|
├── applyVdomOps() — 批量执行 DOM 操作
|
|
803
|
-
└── Frame 处理 lark
|
|
803
|
+
└── Frame 处理 v-lark 子视图 → mountZone
|
|
804
804
|
```
|
|
805
805
|
|
|
806
806
|
对比 React 框架
|
|
@@ -809,7 +809,7 @@ updater.digest()
|
|
|
809
809
|
|
|
810
810
|
React 使用完整的虚拟 DOM 树表示 UI 结构, 通过 JSX 创建 ReactElement 对象树, diff 算法比较新旧两棵虚拟 DOM 树, 生成最小变更集. React 的 diff 算法基于三个假设: 1) 跨层级的节点移动极少, 2) 不同类型的元素产生不同的树, 3) key 属性标识节点的稳定性
|
|
811
811
|
|
|
812
|
-
Lark 不使用完整的虚拟 DOM 树表示, 而是采用增量式 diff: 新模板渲染生成 HTML 字符串, 通过 document.implementation.createHTMLDocument() 解析为真实 DOM 节点, 然后直接与现有 DOM 树进行 diff. 这意味着 Lark 不需要维护一棵独立的虚拟 DOM 树, 内存占用更低. diff 过程中, Lark 的 vdomSetChildNodes 实现了基于 key 的节点匹配 (通过 id,
|
|
812
|
+
Lark 不使用完整的虚拟 DOM 树表示, 而是采用增量式 diff: 新模板渲染生成 HTML 字符串, 通过 document.implementation.createHTMLDocument() 解析为真实 DOM 节点, 然后直接与现有 DOM 树进行 diff. 这意味着 Lark 不需要维护一棵独立的虚拟 DOM 树, 内存占用更低. diff 过程中, Lark 的 vdomSetChildNodes 实现了基于 key 的节点匹配 (通过 id, ldk, v-lark 属性), 类似于 React 的 key 机制, 但匹配策略更简单: 通过哈希表 (keyedNodes) 一次性构建旧节点的 key 映射, 遍历新节点时查找匹配
|
|
813
813
|
|
|
814
814
|
Lark 的 diff 产生四种操作码 (appendChild=1, removeChild=2, replaceChild=4, insertBefore=8), 批量执行; React 的 diff 产生 patch 列表, 通过 React Reconciler 调度执行. Lark 的 diff 是同步的、全量的 (针对单个 View), React 的 diff 可以通过 shouldComponentUpdate / React.memo 等机制跳过子树
|
|
815
815
|
|
|
@@ -825,7 +825,7 @@ React 使用不可变数据模型: setState 生成新的状态对象, 触发组
|
|
|
825
825
|
|
|
826
826
|
事件系统
|
|
827
827
|
|
|
828
|
-
React 使用合成事件 (SyntheticEvent), 在 React 17+ 将事件委托到根容器节点, 事件对象是原生事件的跨浏览器包装. Lark 使用原生事件委托到 document.body, 通过
|
|
828
|
+
React 使用合成事件 (SyntheticEvent), 在 React 17+ 将事件委托到根容器节点, 事件对象是原生事件的跨浏览器包装. Lark 使用原生事件委托到 document.body, 通过 @event 属性编码 View ID 和 handler 名称, EventDelegator 解析分发. Lark 的方案更轻量, 不需要额外的事件对象池和兼容层
|
|
829
829
|
|
|
830
830
|
对比 Vue3 框架
|
|
831
831
|
|
|
@@ -833,7 +833,7 @@ React 使用合成事件 (SyntheticEvent), 在 React 17+ 将事件委托到根
|
|
|
833
833
|
|
|
834
834
|
Vue3 的模板编译器将单文件组件的 <template> 编译为渲染函数, 编译过程分为三步: parse (模板 → AST), transform (AST → JavaScript AST), generate (JavaScript AST → 渲染函数代码). Vue3 的编译器实现了静态提升 (Static Hoisting): 将静态节点提升到渲染函数外部, 避免每次渲染重新创建; PatchFlag 标记动态节点, diff 时只比较标记为动态的部分; Block Tree 优化, 将模板按结构化指令 (v-if, v-for) 拆分为 Block, diff 时扁平化遍历
|
|
835
835
|
|
|
836
|
-
Lark 的模板编译器将 {{}} 语法编译为 JS 函数, 编译过程分为三步: 预处理 (protectComments + processViewEvents), 语法转换 (convertArtSyntax: {{}} → <% %>), 函数生成 (compileToFunction: <% %> → 箭头函数). Lark 的编译器没有 AST 中间表示, 直接通过正则匹配和字符串替换完成转换. Lark 不实现静态提升, 每次渲染完整执行模板函数; 也没有 PatchFlag, 每次渲染产生的 HTML 需要完整 diff. Lark 通过
|
|
836
|
+
Lark 的模板编译器将 {{}} 语法编译为 JS 函数, 编译过程分为三步: 预处理 (protectComments + processViewEvents), 语法转换 (convertArtSyntax: {{}} → <% %>), 函数生成 (compileToFunction: <% %> → 箭头函数). Lark 的编译器没有 AST 中间表示, 直接通过正则匹配和字符串替换完成转换. Lark 不实现静态提升, 每次渲染完整执行模板函数; 也没有 PatchFlag, 每次渲染产生的 HTML 需要完整 diff. Lark 通过 ldk 和 lak 属性提供手动静态跳过能力, 类似于 Vue3 PatchFlag 的手动版本
|
|
837
837
|
|
|
838
838
|
Vue3 的编译器输出 render() 函数, 返回虚拟 DOM 节点树 (VNode), 再由运行时进行 diff; Lark 的编译器输出模板函数, 返回 HTML 字符串, 由 Updater 解析为真实 DOM 后再 diff. Vue3 的编译时优化更丰富, Lark 的编译器更简洁, 依赖运行时 diff 的 keyed 匹配来保证性能
|
|
839
839
|
|
|
@@ -855,7 +855,7 @@ Lark 的 Store 模块同样基于 Proxy 实现响应式, 核心是 createState()
|
|
|
855
855
|
|
|
856
856
|
组件模型
|
|
857
857
|
|
|
858
|
-
Vue3 使用单文件组件 (SFC) 组织视图, <template>, <script>, <style> 放在同一个 .vue 文件中; Lark 将模板 (.html) 和逻辑 (.ts) 分离, 通过 import 关联. Vue3 组件通过 props 接收父组件数据, 通过 emit 向父组件发送事件; Lark View 通过 lark
|
|
858
|
+
Vue3 使用单文件组件 (SFC) 组织视图, <template>, <script>, <style> 放在同一个 .vue 文件中; Lark 将模板 (.html) 和逻辑 (.ts) 分离, 通过 import 关联. Vue3 组件通过 props 接收父组件数据, 通过 emit 向父组件发送事件; Lark View 通过 v-lark 属性传递路径参数, 通过 {{@}} 引用查找传递对象引用, 通过 Frame.invoke 跨层级通信
|
|
859
859
|
|
|
860
860
|
Vue3 的组合式 API (Composition API) 通过 setup() 函数组织逻辑, 使用 ref, reactive, computed, watch 等 API; Lark 的 defineStore creator 函数类似于 setup(), 在其中定义 state 和 handler. Vue3 使用 provide/inject 跨层级传递数据; Lark 使用 State (全局单例) 和 Store (按需创建) 实现跨视图数据共享
|
|
861
861
|
|
|
@@ -882,7 +882,7 @@ Store API
|
|
|
882
882
|
|
|
883
883
|
View 事件绑定
|
|
884
884
|
|
|
885
|
-
模板中通过
|
|
885
|
+
模板中通过 @事件类型 属性绑定事件, 格式为 @click="handlerName()". 支持传参: @click="handlerName({key: value})", JS 对象字面量参数会自动转换为 URL 查询参数格式. 编译时自动编码 View ID 与参数, 运行时由 EventDelegator 解析分发
|
|
886
886
|
|
|
887
887
|
模板语法
|
|
888
888
|
|
|
@@ -14638,17 +14638,17 @@ function restoreComments(source, comments) {
|
|
|
14638
14638
|
}
|
|
14639
14639
|
function processViewEvents(source) {
|
|
14640
14640
|
return source.replace(
|
|
14641
|
-
|
|
14641
|
+
/@(\w+)="([^"]+)"/g,
|
|
14642
14642
|
(fullAttr, eventName, attrValue) => {
|
|
14643
14643
|
const eventMatch = attrValue.match(/^(\w+)\((.*)\)$/s);
|
|
14644
14644
|
if (!eventMatch) return fullAttr;
|
|
14645
14645
|
const handlerName = eventMatch[1];
|
|
14646
14646
|
const paramsStr = eventMatch[2].trim();
|
|
14647
14647
|
if (!paramsStr) {
|
|
14648
|
-
return
|
|
14648
|
+
return `@${eventName}="${VIEW_ID_PLACEHOLDER}${SPLITTER}${handlerName}()"`;
|
|
14649
14649
|
}
|
|
14650
14650
|
const urlParams = jsObjectToUrlParams(paramsStr);
|
|
14651
|
-
return
|
|
14651
|
+
return `@${eventName}="${VIEW_ID_PLACEHOLDER}${SPLITTER}${handlerName}(${urlParams})"`;
|
|
14652
14652
|
}
|
|
14653
14653
|
);
|
|
14654
14654
|
}
|
|
@@ -14874,12 +14874,12 @@ function convertArtExpression(code, debug, lineNo, blockStack = []) {
|
|
|
14874
14874
|
const last = blockStack.pop();
|
|
14875
14875
|
if (!last) {
|
|
14876
14876
|
throw new Error(
|
|
14877
|
-
`[@lark/mvc error
|
|
14877
|
+
`[@lark/mvc error] unexpected {{${code}}}: no matching open block`
|
|
14878
14878
|
);
|
|
14879
14879
|
}
|
|
14880
14880
|
if (last.ctrl !== expectedCtrl) {
|
|
14881
14881
|
throw new Error(
|
|
14882
|
-
`[@lark/mvc error
|
|
14882
|
+
`[@lark/mvc error] unexpected {{${code}}}: expected {{/${last.ctrl}}} to close block opened at line ${last.line}`
|
|
14883
14883
|
);
|
|
14884
14884
|
}
|
|
14885
14885
|
return `${debugPrefix}<%}%>`;
|
|
@@ -15239,19 +15239,18 @@ var BUILTIN_GLOBALS = {
|
|
|
15239
15239
|
// Reference lookup: (refData, value) => key
|
|
15240
15240
|
// Finds or allocates a SPLITTER-prefixed key in refData for a given
|
|
15241
15241
|
// object reference. Used by {{@ref}} operator for passing object
|
|
15242
|
-
// references to child views via lark
|
|
15243
|
-
// Aligned with mx.js Updater_Ref.
|
|
15242
|
+
// references to child views via v-lark attributes.
|
|
15244
15243
|
$i: 1,
|
|
15245
15244
|
// URI encoder: v => encodeURIComponent($n(v)).replace(/[!')(*]/g, extraMap)
|
|
15246
15245
|
// Extends encodeURIComponent with encoding of ! ' ( ) *.
|
|
15247
|
-
// Applied to values in
|
|
15246
|
+
// Applied to values in @event URL parameters and {{!uri}} contexts.
|
|
15248
15247
|
$eu: 1,
|
|
15249
15248
|
// Quote encoder: v => $n(v).replace(/['"\\]/g, '\\$&')
|
|
15250
15249
|
// Escapes quotes and backslashes for safe embedding in HTML attribute
|
|
15251
15250
|
// values (e.g. data-json='...').
|
|
15252
15251
|
$eq: 1,
|
|
15253
15252
|
// View ID — the unique identifier of the owning View instance.
|
|
15254
|
-
// Injected into
|
|
15253
|
+
// Injected into @event attribute values at render time so that
|
|
15255
15254
|
// EventDelegator can dispatch events to the correct View handler.
|
|
15256
15255
|
// The \x1f placeholder in compiled output is replaced with '+$viewId+'.
|
|
15257
15256
|
$viewId: 1,
|