mirror of
https://github.com/smartxworks/sunmao-ui.git
synced 2025-03-31 21:30:22 +08:00
fix(runtime): use proxy when watch and eval slot props
This commit is contained in:
parent
b9880d7d7e
commit
4bc635a9a6
packages/runtime
@ -15,6 +15,7 @@ import {
|
||||
ParentRerenderSchema,
|
||||
MultiSlotsSchema,
|
||||
UpdateTraitPropertiesSchema,
|
||||
EvalSlotPropsWithProxySchema,
|
||||
} from './mockSchema';
|
||||
|
||||
// A pure single sunmao component will render twice when it mount.
|
||||
@ -264,3 +265,20 @@ describe('the `traitPropertiesDidUpdated` lifecircle for trait', () => {
|
||||
clearTesterMap();
|
||||
});
|
||||
});
|
||||
|
||||
describe('component will rerender when slot props changes', () => {
|
||||
it('it will only count once after the states are updated', () => {
|
||||
const { App, stateManager } = initSunmaoUI({ libs: [TestLib] });
|
||||
stateManager.mute = true;
|
||||
const { unmount } = render(<App options={EvalSlotPropsWithProxySchema} />);
|
||||
|
||||
expect(screen.getByTestId('list6_text7_0-text')).toHaveTextContent('1000');
|
||||
act(() => {
|
||||
screen.getByTestId('button5').click();
|
||||
});
|
||||
expect(screen.getByTestId('list6_text7_0-text')).toHaveTextContent('6000');
|
||||
|
||||
unmount();
|
||||
clearTesterMap();
|
||||
});
|
||||
});
|
||||
|
@ -446,3 +446,97 @@ export const UpdateTraitPropertiesSchema: Application = {
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
export const EvalSlotPropsWithProxySchema: Application = {
|
||||
version: 'sunmao/v1',
|
||||
kind: 'Application',
|
||||
metadata: {
|
||||
name: 'some App',
|
||||
},
|
||||
spec: {
|
||||
components: [
|
||||
{
|
||||
id: 'list6',
|
||||
type: 'core/v1/list',
|
||||
properties: {
|
||||
listData: '{{tableData.value}}',
|
||||
},
|
||||
traits: [],
|
||||
},
|
||||
{
|
||||
id: 'text7',
|
||||
type: 'test/v1/tester',
|
||||
properties: {
|
||||
text: '{{$slot.$listItem.salary}}',
|
||||
},
|
||||
traits: [
|
||||
{
|
||||
type: 'core/v2/slot',
|
||||
properties: {
|
||||
container: {
|
||||
id: 'list6',
|
||||
slot: 'content',
|
||||
},
|
||||
ifCondition: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'button5',
|
||||
type: 'test/v1/button',
|
||||
properties: {
|
||||
type: 'default',
|
||||
status: 'default',
|
||||
long: false,
|
||||
size: 'default',
|
||||
disabled: false,
|
||||
loading: false,
|
||||
shape: 'square',
|
||||
text: 'change',
|
||||
},
|
||||
traits: [
|
||||
{
|
||||
type: 'core/v1/event',
|
||||
properties: {
|
||||
handlers: [
|
||||
{
|
||||
type: 'click',
|
||||
componentId: 'tableData',
|
||||
method: {
|
||||
name: 'setValue',
|
||||
parameters: {
|
||||
key: 'value',
|
||||
value:
|
||||
'{{[\n {\n "key": 0,\n "salary": 6000\n },\n {\n "key": 1,\n "salary": 2000\n }\n]}}',
|
||||
},
|
||||
},
|
||||
wait: {
|
||||
type: 'debounce',
|
||||
time: 0,
|
||||
},
|
||||
disabled: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'tableData',
|
||||
type: 'core/v1/dummy',
|
||||
properties: {},
|
||||
traits: [
|
||||
{
|
||||
type: 'core/v1/state',
|
||||
properties: {
|
||||
key: 'value',
|
||||
initialValue:
|
||||
'{{[\n {\n "key": 0,\n "salary": 1000\n },\n {\n "key": 1,\n "salary": 2000\n }\n]}}',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
@ -172,9 +172,18 @@ export class StateManager {
|
||||
): EvaledResult<T> {
|
||||
const store = this.slotStore;
|
||||
|
||||
const redirector = new Proxy(
|
||||
{},
|
||||
{
|
||||
get(_, prop) {
|
||||
return options.slotKey ? store[options.slotKey][prop] : undefined;
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
options.scopeObject = {
|
||||
...options.scopeObject,
|
||||
$slot: options.slotKey ? store[options.slotKey] : undefined,
|
||||
$slot: redirector,
|
||||
};
|
||||
// just eval
|
||||
if (typeof value !== 'string') {
|
||||
@ -201,10 +210,19 @@ export class StateManager {
|
||||
? unknown
|
||||
: PropsAfterEvaled<Exclude<T, string>>;
|
||||
|
||||
const redirector = new Proxy(
|
||||
{},
|
||||
{
|
||||
get(_, prop) {
|
||||
return options.slotKey ? store[options.slotKey][prop] : undefined;
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
const store = this.slotStore;
|
||||
options.scopeObject = {
|
||||
...options.scopeObject,
|
||||
$slot: options.slotKey ? store[options.slotKey] : undefined,
|
||||
$slot: redirector,
|
||||
};
|
||||
// watch change
|
||||
if (value && typeof value === 'object') {
|
||||
|
Loading…
x
Reference in New Issue
Block a user