@proteus-vue/compiler 0.3.0-beta.11 → 0.3.0-beta.12

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/dist/index.js CHANGED
@@ -14716,6 +14716,29 @@ var SEMANTIC_CLASS = {
14716
14716
  a: "proteus-a"
14717
14717
  };
14718
14718
 
14719
+ // src/model-path.ts
14720
+ function modelHandlerSuffix(model) {
14721
+ const raw = String(model ?? "").trim();
14722
+ if (!raw) return "";
14723
+ const segs = raw.replace(/\[([^\]]*)\]/g, ".$1").split(".").map((s) => s.trim()).filter(Boolean);
14724
+ const cap = (s) => s ? s.charAt(0).toUpperCase() + s.slice(1) : "";
14725
+ return segs.map(cap).join("");
14726
+ }
14727
+ function isSimpleModel(model) {
14728
+ return /^[A-Za-z_$][\w$]*$/.test(String(model ?? "").trim());
14729
+ }
14730
+ function setDataEntry(model, valueExpr) {
14731
+ const m = String(model ?? "").trim();
14732
+ if (isSimpleModel(m)) return `${m}: ${valueExpr}`;
14733
+ return `'${m}': ${valueExpr}`;
14734
+ }
14735
+ function inputModelHandler(model) {
14736
+ return `proteusOn${modelHandlerSuffix(model)}Input`;
14737
+ }
14738
+ function componentModelHandler(model) {
14739
+ return `proteusUpdate${modelHandlerSuffix(model)}Model`;
14740
+ }
14741
+
14719
14742
  // src/transforms/template.ts
14720
14743
  function tagRule(id, title, tags, extra) {
14721
14744
  return {
@@ -15217,13 +15240,13 @@ var TEMPLATE_RULES = [
15217
15240
  kind: "component",
15218
15241
  model,
15219
15242
  propName,
15220
- updateHandler: `proteusUpdate${capitalize(model)}Model`
15243
+ updateHandler: componentModelHandler(model)
15221
15244
  };
15222
15245
  } else {
15223
15246
  ctx.output = {
15224
15247
  kind: "input",
15225
15248
  model,
15226
- inputHandler: `proteusOn${capitalize(model)}Input`
15249
+ inputHandler: inputModelHandler(model)
15227
15250
  };
15228
15251
  }
15229
15252
  }
@@ -18879,6 +18902,25 @@ ${inner}
18879
18902
  }
18880
18903
  }
18881
18904
  if (staticStyle) attrs.push(`style="${escapeXml(staticStyle)}"`);
18905
+ {
18906
+ const bindIdx = attrs.map((a, i) => a.startsWith('bindinput="') ? i : -1).filter((i) => i >= 0);
18907
+ if (bindIdx.length > 1) {
18908
+ const names = bindIdx.map((i) => /bindinput="([^"]*)"/.exec(attrs[i])?.[1] ?? "").filter(Boolean);
18909
+ const [vmodelHandler, ...userHandlers] = names;
18910
+ const suffix2 = vmodelHandler.replace(/^proteusOn/, "").replace(/Input$/, "");
18911
+ const merged = `proteusMerge${suffix2}And${userHandlers.map((h) => h.charAt(0).toUpperCase() + h.slice(1)).join("And")}`;
18912
+ if (!ctx.vModelMergedHandlers.some((h) => h.name === merged)) {
18913
+ ctx.vModelMergedHandlers.push({ name: merged, calls: [vmodelHandler, ...userHandlers] });
18914
+ }
18915
+ for (const i of [...bindIdx].reverse()) attrs.splice(i, 1);
18916
+ attrs.push(`bindinput="${merged}"`);
18917
+ ctx.trace?.add("directive/v-model", {
18918
+ line: node.loc.start.line,
18919
+ before: `v-model + ${userHandlers.map((h) => "@input=" + h).join(" / ")}\uFF08\u540C\u5143\u7D20 \u2192 bindinput \u91CD\u590D\uFF09`,
18920
+ after: `bindinput="${merged}"\uFF08\u5408\u5E76\uFF1A\u5148\u56DE\u5199\u518D\u8C03\u7528\u6237 handler\uFF09`
18921
+ });
18922
+ }
18923
+ }
18882
18924
  const attrStr = attrs.length ? ` ${attrs.join(" ")}` : "";
18883
18925
  const lineNote = ctx.annotateLines ? `<!-- @${node.loc.start.line} ${node.tag} -->
18884
18926
  ` : "";
@@ -19038,6 +19080,7 @@ function transformTemplateToWxml(source, opts = { px2rpx: true, rpxRatio: 2, ann
19038
19080
  // ★2026-09-08 useTemplateRef/模板 ref 承接(ref="x" → id + 收集)
19039
19081
  templateRefNames: /* @__PURE__ */ new Set(),
19040
19082
  vModelComponentHandlers: [],
19083
+ vModelMergedHandlers: [],
19041
19084
  // ★#496 柔性语义编译:p-grid 收集
19042
19085
  semanticGrids: [],
19043
19086
  isPage: opts.isComponent !== true,
@@ -19113,6 +19156,7 @@ ${inner}
19113
19156
  dynamicSvgs: ctx.dynamicSvgs,
19114
19157
  // ★#500 自定义组件 v-model 回写处理器
19115
19158
  vModelComponentHandlers: ctx.vModelComponentHandlers,
19159
+ vModelMergedHandlers: ctx.vModelMergedHandlers,
19116
19160
  semanticGrids: ctx.semanticGrids,
19117
19161
  // ★15-page-scroll-container:已自动包滚动容器(compileVueSfc 据此注入高度样式)
19118
19162
  pageScrollWrapped: autoScroll && !alreadyScroll,
@@ -22091,16 +22135,22 @@ function transformScriptToPage(source, _opts = { px2rpx: true, rpxRatio: 2 }, ex
22091
22135
  const vmodelDisabled = disabled.has("script/vmodel-handler");
22092
22136
  for (const name of vModelBindings) {
22093
22137
  if (!vmodelDisabled) {
22094
- methodNames.add(`proteusOn${capitalize2(name)}Input`);
22095
- pushMethod(` proteusOn${capitalize2(name)}Input(e) { this.setData({ ${name}: e.detail.value }) },`);
22138
+ methodNames.add(inputModelHandler(name));
22139
+ pushMethod(` ${inputModelHandler(name)}(e) { this.setData({ ${setDataEntry(name, "e.detail.value")} }) },`);
22096
22140
  }
22097
22141
  }
22098
22142
  for (const h of extra.vModelComponentHandlers ?? []) {
22099
22143
  if (!vmodelDisabled) {
22100
22144
  methodNames.add(h.name);
22101
- pushMethod(` ${h.name}(e) { this.setData({ ${h.model}: e.detail }) },`);
22145
+ pushMethod(` ${h.name}(e) { this.setData({ ${setDataEntry(h.model, "e.detail")} }) },`);
22102
22146
  }
22103
22147
  }
22148
+ for (const h of extra.vModelMergedHandlers ?? []) {
22149
+ if (vmodelDisabled) continue;
22150
+ methodNames.add(h.name);
22151
+ const body = h.calls.map((c) => `this.${c}(e)`).join("; ");
22152
+ pushMethod(` ${h.name}(e) { ${body} },`);
22153
+ }
22104
22154
  if (vModelBindings.length && !vmodelDisabled) {
22105
22155
  trace?.add("script/vmodel-handler", {
22106
22156
  before: `v-model="${vModelBindings.join('", "')}"`,
@@ -23188,6 +23238,8 @@ function compileVueSfc(source, options = {}) {
23188
23238
  dynamicSvgs: tplResult.dynamicSvgs,
23189
23239
  // ★#500 自定义组件 v-model 回写处理器
23190
23240
  vModelComponentHandlers: tplResult.vModelComponentHandlers,
23241
+ // ★2026-09-20(F-28/Bug E):v-model + @input 同元素 → 合并处理器(script 生成方法)
23242
+ vModelMergedHandlers: tplResult.vModelMergedHandlers,
23191
23243
  semanticGrids: tplResult.semanticGrids,
23192
23244
  moduleImports: options.moduleImports,
23193
23245
  modelRefs: sfcMacros.ok ? sfcMacros.modelRefs : void 0,
@@ -0,0 +1,14 @@
1
+ /** 路径 → 合法标识符片段(各段首字母大写并拼接;非标识符字符丢弃后按段切分) */
2
+ export declare function modelHandlerSuffix(model: string): string;
3
+ /** 绑定表达式是否为**简单标识符**(无路径)——简单标识符可走原来的简洁产物,路径才需要特殊处理 */
4
+ export declare function isSimpleModel(model: string): boolean;
5
+ /**
6
+ * setData 条目文本。
7
+ * · 简单标识符 → `name: expr`(与原产物一致,保持向后兼容)
8
+ * · 路径 → `'a.b': expr` / `'arr[0]': expr`(**键加引号**;小程序 setData 支持路径键写入嵌套字段)
9
+ */
10
+ export declare function setDataEntry(model: string, valueExpr: string): string;
11
+ /** v-model(原生/input 形态)的 handler 名——template 与 script 两侧共用 */
12
+ export declare function inputModelHandler(model: string): string;
13
+ /** v-model(组件形态,回写目标)的 handler 名——同上 */
14
+ export declare function componentModelHandler(model: string): string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@proteus-vue/compiler",
3
- "version": "0.3.0-beta.11",
3
+ "version": "0.3.0-beta.12",
4
4
  "description": "Proteus 编译引擎 —— 标准 Vue SFC → 小程序四件套(纯函数、零运行时依赖、规则注册表 + AI 说明书)",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -42,7 +42,7 @@
42
42
  "@babel/plugin-transform-optional-chaining": "^7.29.0",
43
43
  "@proteus-vue/component-ir": "0.3.0-beta.11",
44
44
  "@proteus-vue/contracts": "0.3.0-beta.11",
45
- "@proteus-vue/types": "0.3.0-beta.11"
45
+ "@proteus-vue/types": "0.3.0-beta.12"
46
46
  },
47
47
  "scripts": {
48
48
  "build": "tsc -p tsconfig.build.json --emitDeclarationOnly && esbuild src/index.ts src/style-safety/index.ts --bundle --format=esm --platform=node --outdir=dist --external:@vue/compiler-sfc --external:@vue/compiler-dom --external:@proteus-vue/contracts --external:@proteus-vue/component-ir --external:@babel/core --external:@babel/plugin-transform-nullish-coalescing-operator --external:@babel/plugin-transform-optional-chaining --external:@babel/plugin-transform-logical-assignment-operators --external:@babel/plugin-transform-object-rest-spread"