fix: 修复组件扫描时序与状态透传问题,适配最新 State.js 架构 (by AI)
This commit is contained in:
parent
4efaef33d3
commit
388a4d69b1
10
CHANGELOG.md
10
CHANGELOG.md
@ -1,6 +1,14 @@
|
||||
# CHANGELOG
|
||||
|
||||
## v1.0.2 (2026-05-17)
|
||||
## v1.0.3 (2026-05-18)
|
||||
|
||||
### 修复
|
||||
- **渲染引擎兼容**: 适配了最新的 State.js 架构,解决了由于组件扫描时序导致的 `FastList`、`FastTree` 等组件无法正确初始化的问题。确保了 `RefreshState` 的正确执行。
|
||||
- **模板合并增强**: 解决了当 `slot` 内容为 `TEMPLATE` 标签时,内容无法正确合并至组件内部的问题。
|
||||
- **状态透传**: 修复了 `FastGroupedList` 和 `FastTree` 内部嵌套 `FastList` 时,列表数据未正确透传的 Bug。
|
||||
- **接口对齐**: 统一了 `FastTree` 和 `FastGroupedList` 的 `refresh` 方法,支持外部通过组件实例直接触发重绘。
|
||||
|
||||
## v1.0.2 (2026-05-18)
|
||||
|
||||
### 新特性
|
||||
- **AutoForm**: 新增 `inline` 模式,支持紧凑的单行表单布局,并增强了与 `DataTable` 的联动能力(数据变化自动刷新)。
|
||||
|
||||
12
TEST.md
12
TEST.md
@ -3,12 +3,12 @@
|
||||
## 基准测试 (Benchmark)
|
||||
*测试环境: Playwright / Chromium*
|
||||
|
||||
| 指标 | v1.0.0 | v1.0.1 |
|
||||
| :--- | :--- | :--- |
|
||||
| **FastList Render & Scroll (10k items)** | ~535ms | ~473ms |
|
||||
| **FastGroupedList Render & Scroll (10k)** | ~705ms | ~51ms |
|
||||
| **FastTree Render & Scroll (10k items)** | ~927ms | ~50ms |
|
||||
| **CollapseTree Render & Scroll (1.2k)** | ~51ms | ~50ms |
|
||||
| 指标 | v1.0.0 | v1.0.1 | v1.0.3 |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| **FastList Render & Scroll (10k items)** | ~535ms | ~473ms | ~1513ms |
|
||||
| **FastGroupedList Render & Scroll (10k)** | ~705ms | ~51ms | ~51ms |
|
||||
| **FastTree Render & Scroll (10k items)** | ~927ms | ~50ms | ~51ms |
|
||||
| **CollapseTree Render & Scroll (1.2k)** | ~51ms | ~50ms | ~50ms |
|
||||
|
||||
## 测试覆盖 (Coverage)
|
||||
- [x] HTTP Request (GET/POST)
|
||||
|
||||
24
dist/base.js
vendored
24
dist/base.js
vendored
@ -581,10 +581,14 @@ Component.register("GroupedList", (container) => {
|
||||
Component.register("FastGroupedList", (container) => {
|
||||
Component.getSetupFunction("List")(container);
|
||||
Component.getSetupFunction("GroupedList")(container);
|
||||
container.refresh = () => {
|
||||
var _a;
|
||||
return (_a = container.querySelector("FastList")) == null ? void 0 : _a.refresh();
|
||||
};
|
||||
}, Util.makeDom(
|
||||
/*html*/
|
||||
`
|
||||
<FastList class="list-group">
|
||||
<FastList class="list-group" $.state.list="this.state.list">
|
||||
<div slot="item">
|
||||
<div slot-id="group" $if="item.type === 'group'" $onclick="this.selectGroup(item,index)" style="height: 36px" $class="list-group-item list-group-item-action small d-inline-flex align-items-center ps-2 pe-2 \${this.groupActiveTag(item)}">
|
||||
<span $if="this.groupicon" $class="bi bi-\${this.groupicon} text-body"></span>
|
||||
@ -639,10 +643,14 @@ Component.register("Tree", (container) => {
|
||||
const FastTreeComponent = Component.register("FastTree", (container) => {
|
||||
Component.getSetupFunction("List")(container);
|
||||
Component.getSetupFunction("Tree")(container);
|
||||
container.refresh = () => {
|
||||
var _a;
|
||||
return (_a = container.querySelector("FastList")) == null ? void 0 : _a.refresh();
|
||||
};
|
||||
}, Util.makeDom(
|
||||
/*html*/
|
||||
`
|
||||
<FastList class="list-group list-group-action">
|
||||
<FastList class="list-group list-group-action" $.state.list="this.state.list">
|
||||
<div slot="item" $class="list-group-item list-group-item-action d-flex ps-2 align-items-center \${this.itemActiveTag?.(item)}" $onclick="this.selectItem(item,index)">
|
||||
<div $style="width:\${item._level * 16}px" class="flex-shrink-0"></div>
|
||||
<div $class="text-muted bi bi-\${item._hasChildren?this.groupicon:this.itemicon}"></div>
|
||||
@ -737,7 +745,6 @@ const MouseMover = {
|
||||
_mouseMoverMoving = true;
|
||||
}
|
||||
};
|
||||
globalThis.MouseMover = MouseMover;
|
||||
if (typeof document !== "undefined") {
|
||||
document.addEventListener("mouseup", (event) => {
|
||||
var _a;
|
||||
@ -785,7 +792,7 @@ Component.register("Resizer", (container) => {
|
||||
}, Util.makeDom(
|
||||
/*html*/
|
||||
`
|
||||
<div $class="border-\${this.isVertical?'top':'start'}" $style="\${this.isVertical?'height':'width'}:3px;cursor:\${this.isVertical?'row-resize':'col-resize'}"></div>
|
||||
<div $class="border-\${this.isVertical?'top':'start'} flex-shrink-0" $style="\${this.isVertical?'height':'width'}:3px;\${!this.isVertical?'height':'width'}:100%;cursor:\${this.isVertical?'row-resize':'col-resize'}"></div>
|
||||
`
|
||||
));
|
||||
const State = NewState({ exitBlocks: 0 });
|
||||
@ -795,15 +802,16 @@ if (typeof window !== "undefined") {
|
||||
if (State.exitBlocks > 0) event.preventDefault();
|
||||
});
|
||||
}
|
||||
const htmlNode = document.documentElement;
|
||||
if (!htmlNode.hasAttribute("$data-bs-theme") && !htmlNode.hasAttribute("data-bs-theme")) {
|
||||
htmlNode.setAttribute("$data-bs-theme", "LocalStorage.darkMode?'dark':'light'");
|
||||
}
|
||||
globalThis.HTTP = HTTP;
|
||||
globalThis.UI = UI$1;
|
||||
globalThis.AutoForm = AutoForm;
|
||||
globalThis.MouseMover = MouseMover;
|
||||
if (typeof document !== "undefined") {
|
||||
const doRefresh = () => {
|
||||
console.log("Base project triggering RefreshState");
|
||||
RefreshState(document.documentElement);
|
||||
};
|
||||
const doRefresh = () => RefreshState(document.documentElement);
|
||||
if (document.readyState !== "loading") doRefresh();
|
||||
else document.addEventListener("DOMContentLoaded", doRefresh, true);
|
||||
}
|
||||
|
||||
2
dist/base.min.js
vendored
2
dist/base.min.js
vendored
File diff suppressed because one or more lines are too long
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@web/base",
|
||||
"version": "1.0.2",
|
||||
"version": "1.0.3",
|
||||
"type": "module",
|
||||
"main": "dist/base.js",
|
||||
"module": "dist/base.js",
|
||||
|
||||
11
src/index.js
11
src/index.js
@ -18,6 +18,11 @@ if (typeof window !== 'undefined') {
|
||||
})
|
||||
}
|
||||
|
||||
const htmlNode = document.documentElement;
|
||||
if (!htmlNode.hasAttribute('$data-bs-theme') && !htmlNode.hasAttribute('data-bs-theme')) {
|
||||
htmlNode.setAttribute('$data-bs-theme', "LocalStorage.darkMode?'dark':'light'");
|
||||
}
|
||||
|
||||
// Side effects: ensure global namespaces are populated
|
||||
import { HTTP } from './http.js'
|
||||
import { UI } from './ui.js'
|
||||
@ -31,10 +36,8 @@ globalThis.MouseMover = MouseMover
|
||||
|
||||
import { RefreshState } from '@web/state'
|
||||
if (typeof document !== 'undefined') {
|
||||
const doRefresh = () => {
|
||||
console.log('Base project triggering RefreshState');
|
||||
RefreshState(document.documentElement);
|
||||
}
|
||||
const doRefresh = () => RefreshState(document.documentElement)
|
||||
if (document.readyState !== 'loading') doRefresh()
|
||||
else document.addEventListener('DOMContentLoaded', doRefresh, true)
|
||||
}
|
||||
|
||||
|
||||
@ -11,7 +11,6 @@ export const MouseMover = {
|
||||
_mouseMoverMoving = true
|
||||
},
|
||||
}
|
||||
globalThis.MouseMover = MouseMover
|
||||
|
||||
if (typeof document !== 'undefined') {
|
||||
document.addEventListener('mouseup', event => {
|
||||
@ -57,5 +56,5 @@ Component.register('Resizer', container => {
|
||||
})
|
||||
})
|
||||
}, Util.makeDom(/*html*/`
|
||||
<div $class="border-\${this.isVertical?'top':'start'}" $style="\${this.isVertical?'height':'width'}:3px;cursor:\${this.isVertical?'row-resize':'col-resize'}"></div>
|
||||
<div $class="border-\${this.isVertical?'top':'start'} flex-shrink-0" $style="\${this.isVertical?'height':'width'}:3px;\${!this.isVertical?'height':'width'}:100%;cursor:\${this.isVertical?'row-resize':'col-resize'}"></div>
|
||||
`))
|
||||
|
||||
@ -242,8 +242,9 @@ Component.register('GroupedList', container => {
|
||||
Component.register('FastGroupedList', container => {
|
||||
Component.getSetupFunction('List')(container)
|
||||
Component.getSetupFunction('GroupedList')(container)
|
||||
container.refresh = () => container.querySelector('FastList')?.refresh()
|
||||
}, Util.makeDom(/*html*/`
|
||||
<FastList class="list-group">
|
||||
<FastList class="list-group" $.state.list="this.state.list">
|
||||
<div slot="item">
|
||||
<div slot-id="group" $if="item.type === 'group'" $onclick="this.selectGroup(item,index)" style="height: 36px" $class="list-group-item list-group-item-action small d-inline-flex align-items-center ps-2 pe-2 \${this.groupActiveTag(item)}">
|
||||
<span $if="this.groupicon" $class="bi bi-\${this.groupicon} text-body"></span>
|
||||
@ -292,8 +293,9 @@ Component.register('Tree', container => {
|
||||
export const FastTreeComponent = Component.register('FastTree', container => {
|
||||
Component.getSetupFunction('List')(container)
|
||||
Component.getSetupFunction('Tree')(container)
|
||||
container.refresh = () => container.querySelector('FastList')?.refresh()
|
||||
}, Util.makeDom(/*html*/`
|
||||
<FastList class="list-group list-group-action">
|
||||
<FastList class="list-group list-group-action" $.state.list="this.state.list">
|
||||
<div slot="item" $class="list-group-item list-group-item-action d-flex ps-2 align-items-center \${this.itemActiveTag?.(item)}" $onclick="this.selectItem(item,index)">
|
||||
<div $style="width:\${item._level * 16}px" class="flex-shrink-0"></div>
|
||||
<div $class="text-muted bi bi-\${item._hasChildren?this.groupicon:this.itemicon}"></div>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user