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
|
# 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` 的联动能力(数据变化自动刷新)。
|
- **AutoForm**: 新增 `inline` 模式,支持紧凑的单行表单布局,并增强了与 `DataTable` 的联动能力(数据变化自动刷新)。
|
||||||
|
|||||||
12
TEST.md
12
TEST.md
@ -3,12 +3,12 @@
|
|||||||
## 基准测试 (Benchmark)
|
## 基准测试 (Benchmark)
|
||||||
*测试环境: Playwright / Chromium*
|
*测试环境: Playwright / Chromium*
|
||||||
|
|
||||||
| 指标 | v1.0.0 | v1.0.1 |
|
| 指标 | v1.0.0 | v1.0.1 | v1.0.3 |
|
||||||
| :--- | :--- | :--- |
|
| :--- | :--- | :--- | :--- |
|
||||||
| **FastList Render & Scroll (10k items)** | ~535ms | ~473ms |
|
| **FastList Render & Scroll (10k items)** | ~535ms | ~473ms | ~1513ms |
|
||||||
| **FastGroupedList Render & Scroll (10k)** | ~705ms | ~51ms |
|
| **FastGroupedList Render & Scroll (10k)** | ~705ms | ~51ms | ~51ms |
|
||||||
| **FastTree Render & Scroll (10k items)** | ~927ms | ~50ms |
|
| **FastTree Render & Scroll (10k items)** | ~927ms | ~50ms | ~51ms |
|
||||||
| **CollapseTree Render & Scroll (1.2k)** | ~51ms | ~50ms |
|
| **CollapseTree Render & Scroll (1.2k)** | ~51ms | ~50ms | ~50ms |
|
||||||
|
|
||||||
## 测试覆盖 (Coverage)
|
## 测试覆盖 (Coverage)
|
||||||
- [x] HTTP Request (GET/POST)
|
- [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.register("FastGroupedList", (container) => {
|
||||||
Component.getSetupFunction("List")(container);
|
Component.getSetupFunction("List")(container);
|
||||||
Component.getSetupFunction("GroupedList")(container);
|
Component.getSetupFunction("GroupedList")(container);
|
||||||
|
container.refresh = () => {
|
||||||
|
var _a;
|
||||||
|
return (_a = container.querySelector("FastList")) == null ? void 0 : _a.refresh();
|
||||||
|
};
|
||||||
}, Util.makeDom(
|
}, Util.makeDom(
|
||||||
/*html*/
|
/*html*/
|
||||||
`
|
`
|
||||||
<FastList class="list-group">
|
<FastList class="list-group" $.state.list="this.state.list">
|
||||||
<div slot="item">
|
<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)}">
|
<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>
|
<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) => {
|
const FastTreeComponent = Component.register("FastTree", (container) => {
|
||||||
Component.getSetupFunction("List")(container);
|
Component.getSetupFunction("List")(container);
|
||||||
Component.getSetupFunction("Tree")(container);
|
Component.getSetupFunction("Tree")(container);
|
||||||
|
container.refresh = () => {
|
||||||
|
var _a;
|
||||||
|
return (_a = container.querySelector("FastList")) == null ? void 0 : _a.refresh();
|
||||||
|
};
|
||||||
}, Util.makeDom(
|
}, Util.makeDom(
|
||||||
/*html*/
|
/*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 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 $style="width:\${item._level * 16}px" class="flex-shrink-0"></div>
|
||||||
<div $class="text-muted bi bi-\${item._hasChildren?this.groupicon:this.itemicon}"></div>
|
<div $class="text-muted bi bi-\${item._hasChildren?this.groupicon:this.itemicon}"></div>
|
||||||
@ -737,7 +745,6 @@ const MouseMover = {
|
|||||||
_mouseMoverMoving = true;
|
_mouseMoverMoving = true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
globalThis.MouseMover = MouseMover;
|
|
||||||
if (typeof document !== "undefined") {
|
if (typeof document !== "undefined") {
|
||||||
document.addEventListener("mouseup", (event) => {
|
document.addEventListener("mouseup", (event) => {
|
||||||
var _a;
|
var _a;
|
||||||
@ -785,7 +792,7 @@ Component.register("Resizer", (container) => {
|
|||||||
}, Util.makeDom(
|
}, Util.makeDom(
|
||||||
/*html*/
|
/*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 });
|
const State = NewState({ exitBlocks: 0 });
|
||||||
@ -795,15 +802,16 @@ if (typeof window !== "undefined") {
|
|||||||
if (State.exitBlocks > 0) event.preventDefault();
|
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.HTTP = HTTP;
|
||||||
globalThis.UI = UI$1;
|
globalThis.UI = UI$1;
|
||||||
globalThis.AutoForm = AutoForm;
|
globalThis.AutoForm = AutoForm;
|
||||||
globalThis.MouseMover = MouseMover;
|
globalThis.MouseMover = MouseMover;
|
||||||
if (typeof document !== "undefined") {
|
if (typeof document !== "undefined") {
|
||||||
const doRefresh = () => {
|
const doRefresh = () => RefreshState(document.documentElement);
|
||||||
console.log("Base project triggering RefreshState");
|
|
||||||
RefreshState(document.documentElement);
|
|
||||||
};
|
|
||||||
if (document.readyState !== "loading") doRefresh();
|
if (document.readyState !== "loading") doRefresh();
|
||||||
else document.addEventListener("DOMContentLoaded", doRefresh, true);
|
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",
|
"name": "@web/base",
|
||||||
"version": "1.0.2",
|
"version": "1.0.3",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "dist/base.js",
|
"main": "dist/base.js",
|
||||||
"module": "dist/base.js",
|
"module": "dist/base.js",
|
||||||
|
|||||||
15
src/index.js
15
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
|
// Side effects: ensure global namespaces are populated
|
||||||
import { HTTP } from './http.js'
|
import { HTTP } from './http.js'
|
||||||
import { UI } from './ui.js'
|
import { UI } from './ui.js'
|
||||||
@ -31,10 +36,8 @@ globalThis.MouseMover = MouseMover
|
|||||||
|
|
||||||
import { RefreshState } from '@web/state'
|
import { RefreshState } from '@web/state'
|
||||||
if (typeof document !== 'undefined') {
|
if (typeof document !== 'undefined') {
|
||||||
const doRefresh = () => {
|
const doRefresh = () => RefreshState(document.documentElement)
|
||||||
console.log('Base project triggering RefreshState');
|
if (document.readyState !== 'loading') doRefresh()
|
||||||
RefreshState(document.documentElement);
|
else document.addEventListener('DOMContentLoaded', doRefresh, true)
|
||||||
}
|
|
||||||
if (document.readyState !== 'loading') doRefresh()
|
|
||||||
else document.addEventListener('DOMContentLoaded', doRefresh, true)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -11,7 +11,6 @@ export const MouseMover = {
|
|||||||
_mouseMoverMoving = true
|
_mouseMoverMoving = true
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
globalThis.MouseMover = MouseMover
|
|
||||||
|
|
||||||
if (typeof document !== 'undefined') {
|
if (typeof document !== 'undefined') {
|
||||||
document.addEventListener('mouseup', event => {
|
document.addEventListener('mouseup', event => {
|
||||||
@ -57,5 +56,5 @@ Component.register('Resizer', container => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
}, Util.makeDom(/*html*/`
|
}, 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.register('FastGroupedList', container => {
|
||||||
Component.getSetupFunction('List')(container)
|
Component.getSetupFunction('List')(container)
|
||||||
Component.getSetupFunction('GroupedList')(container)
|
Component.getSetupFunction('GroupedList')(container)
|
||||||
|
container.refresh = () => container.querySelector('FastList')?.refresh()
|
||||||
}, Util.makeDom(/*html*/`
|
}, Util.makeDom(/*html*/`
|
||||||
<FastList class="list-group">
|
<FastList class="list-group" $.state.list="this.state.list">
|
||||||
<div slot="item">
|
<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)}">
|
<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>
|
<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 => {
|
export const FastTreeComponent = Component.register('FastTree', container => {
|
||||||
Component.getSetupFunction('List')(container)
|
Component.getSetupFunction('List')(container)
|
||||||
Component.getSetupFunction('Tree')(container)
|
Component.getSetupFunction('Tree')(container)
|
||||||
|
container.refresh = () => container.querySelector('FastList')?.refresh()
|
||||||
}, Util.makeDom(/*html*/`
|
}, 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 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 $style="width:\${item._level * 16}px" class="flex-shrink-0"></div>
|
||||||
<div $class="text-muted bi bi-\${item._hasChildren?this.groupicon:this.itemicon}"></div>
|
<div $class="text-muted bi bi-\${item._hasChildren?this.groupicon:this.itemicon}"></div>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user