逻辑层(wadLogicLayer)
逻辑层脚本(<script type="text/wad-logic">)运行在小程序的 appservice V8 上下文:有 wx,无 DOM。注入位置是业务上下文(WxaSub-*),不是 MainContext。
本层 API 已拍平:直接
wadLogicLayer.page(),不存在wadLogicLayer.logicLayer.page()。逻辑层没有指向自己的自引用代理——logicLayer/renderLayer/panelLayer这三个子命名空间只作为跨层代理出现。
本页你将学到
wadLogicLayer顶层的全部本地 API(同步/异步差异);call的可变参语义(数组就是一个普通参数);- 逻辑层如何经
renderLayer/panelLayer代理跨层; - 哪些调用会报
E_LAYER_ONLY。
page()
读当前页面。同步直调。
- 签名:
page() → {route, options}
var p = wadLogicLayer.page();
// {route: 'pages/index/index', options: {id: '42'}}register(n, fn)
注册技能。面板、渲染层、宿主都通过 call(n, ...args) 调用它(详见 插件多层函数)。
- 签名:
register(name, fn) → wadLogicLayer
wadLogicLayer.register('cart.count', function () {
return wx.getStorageSync('cart_items').length;
});注意点:同名重复注册后注册覆盖先注册;attach 每次注入都会重发,注册要幂等。
call(n, ...args)
调用本层已注册技能。可变参,同步直调。
- 签名:
call(name, arg1, arg2, …) → 返回值(同步) - 数组就是一个普通参数:
call('add', [1, 2])传的是「一个数组」,不是两个参数。
var n = wadLogicLayer.call('add', 1, 2); // 3,本层同步直调
var r = wadLogicLayer.call('sumAll', [1, 2, 3]); // 把数组整体作为一个参数eval(expr)
逻辑层业务沙箱禁用 eval / new Function(WMPF 运行时限制,实测 TypeError: eval is not a function)。 wadLogicLayer.eval() 会同步抛 E_EVAL_SANDBOX,不会返回结果。
需要求值时改用:
(async () => {
// 1) 逻辑层上下文求值(异步,需 debugger 可用)
var r = await wadLogicLayer.debugger.evalGlobal('getCurrentPages().length');
// 2) 页面上下文求值(同步,在渲染层)
var len = wadRenderLayer.eval('document.querySelectorAll("*").length');
})();- 签名:
eval(expr) → never(抛E_EVAL_SANDBOX) - 错误码:
E_EVAL_SANDBOX
storage.*
操作小程序 wx storage,插件命名空间(key 前缀 __wad_<id>_)。Promise 与同步两套形态,详见 存储。
- Promise:
storage.get / set / remove / keys / clear - 同步:
storage.getSync / setSync / removeSync / keysSync / clearSync
(async () => {
wadLogicLayer.storage.setSync('lastRoute', 'pages/index/index'); // 同步写
var v = wadLogicLayer.storage.getSync('lastRoute');
await wadLogicLayer.storage.set('note', '异步写的'); // Promise 写
})();ui.toast(t)
投递宿主 Toast。
- 签名:
ui.toast(text)
wadLogicLayer.ui.toast('已保存');on(name, fn) / off(name, fn)
订阅逻辑层本层事件(attach / pageChange / storageWrite…,见 事件系统)。顶层 emit 投递到本插件面板。
wadLogicLayer.on('pageChange', function (p) { track(p.route); });
wadLogicLayer.emit('scan-state', { done: 42 }); // → 本插件面板钩子糖
| 钩子 | 触发时机 |
|---|---|
onReady(fn) | 注入完成 |
onAttach(fn) / onDetach(fn) | 每次注入 / 配置移除 |
onPageChange(fn) | 业务路由变化 |
onStorageWrite(fn) | 业务写 wx storage |
onNetwork(fn) | 网络摘要 |
全部返回解绑函数(详见 生命周期与回调)。
const off = wadLogicLayer.onPageChange(function (p) {
wadLogicLayer.log('route: ' + p.route);
});tools / http / messaging / sharedStorage / capture / native / assets / debugger
逻辑层顶层都可用,语义如下:
| 命名空间 | 语义 |
|---|---|
tools.* | 工具包,与渲染/面板同一实现(见 tools) |
http.* | wx.request 语义,默认 dataType: 'json',task 可 abort()(见 HTTP) |
messaging.* | 三层广播,emit → Promise<payload>(见 messaging) |
sharedStorage.app / global / watch | 跨层共享存储(见 sharedStorage) |
capture.* | intercept / watch / records / body / rules / addRule→Promise<{id}> / removeRule / clear(见 capture) |
native.* | intercept / observe / records / get / clear(见 通过插件 · Native脚本) |
assets.* | url / text / json / arrayBuffer / wasm / preload / clear;script/css 返回 Promise.reject E_LAYER_ONLY(见 assets) |
debugger.* | 断点调试全量(见 Debugger API) |
(async () => {
// 逻辑层网络与工具
const res = await wadLogicLayer.http.get('https://httpbin.org/get');
const sign = wadLogicLayer.tools.hmacSha256(secret, ts + body);
})();跨层代理:renderLayer
逻辑层经 wadLogicLayer.renderLayer 访问渲染层:
| API | 签名 | 说明 |
|---|---|---|
renderLayer.eval(expr) | → null | fire-and-forget:投递到页面执行,不等结果 |
renderLayer.page() | Promise<{url, title}> | 经宿主问渲染层当前页面 |
renderLayer.screenshot(opts) | opts: {upload?} | 页面截图(PNG base64;upload 非空时宿主直传该 URL) |
renderLayer.domSnapshot(opts) | opts: {tree?, upload?} | 全量 DOM(tree:true 附带 CDP DOM 树;route 仅面板代理支持) |
renderLayer.ui.toast(t) | 宿主 Toast | |
renderLayer.tools | 同本层 tools |
// <script type="text/wad-logic"> 内
(async () => {
wadLogicLayer.renderLayer.eval('document.title = "WAD"'); // 不等结果
var p = await wadLogicLayer.renderLayer.page(); // {url, title}
var shot = await wadLogicLayer.renderLayer.screenshot(); // {ok, png_b64, target}
})();注意点:渲染层注入是短连接,页面切换自动重注入;eval 投递到当前页面。
跨层代理:panelLayer
逻辑层经 wadLogicLayer.panelLayer 只有面板 UI 与工具两个入口:
| API | 说明 |
|---|---|
panelLayer.ui.toast(t) | 宿主 Toast(面板壳展示) |
panelLayer.tools | 同本层 tools |
wadLogicLayer.panelLayer.ui.toast('逻辑层发出的提示');E_LAYER_ONLY 一览
| API | 逻辑层本地 | 经代理可用 | 不可用 |
|---|---|---|---|
page / register / storage.*Sync | ✅ 本地 | —(面板经 logicLayer.page;渲染层不可用) | 渲染层 |
eval | ⛔ 本地抛 E_EVAL_SANDBOX | 🔁 面板 logicLayer.eval 可用 | 渲染层本地有 eval |
capture.intercept / native.intercept | ✅ 本地 | — | 渲染层/面板均同步抛 E_LAYER_ONLY |
assets.script / css | ❌ Promise.reject | — | 渲染/面板 ✅ |
renderLayer.dom.* | —(dom 只在渲染层本地) | — | 面板(无此代理成员) |
panelLayer.storage / panelLayer.on | — | — | 面板本地才能调 |
// 逻辑层调不可用的资产加载:
wadLogicLayer.assets.script('assets/x.js').catch(function (e) {
e.code === 'E_LAYER_ONLY'; // true
});完整示例:页面路由监控
<script type="text/wad-logic">
wadLogicLayer.onPageChange(function (p) {
// 记录路径栈,供面板查询
var stack = wx.getStorageSync('__wad_routes__') || [];
stack.push({ route: p.route, at: Date.now() });
wx.setStorageSync('__wad_routes__', stack.slice(-100));
});
wadLogicLayer.register('routes', function () {
return wx.getStorageSync('__wad_routes__') || [];
});
</script>
<script>
// 面板:调逻辑层技能(可变参)
wadPanelLayer.ready.then(function () {
wadPanelLayer.logicLayer.call('routes').then(function (list) {
document.body.textContent = list.map(function (r) { return r.route; }).join('\n');
});
});
</script>