mirror of https://github.com/sveltejs/svelte
parent
9a78da982b
commit
0f09d5a4f7
@ -0,0 +1,34 @@
|
|||||||
|
/** @import { Expression, Property } from 'estree' */
|
||||||
|
/** @import { ComponentContext, Context } from '../../types' */
|
||||||
|
import * as b from '#compiler/builders';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The `onchange` callback from a `$state` rune's options argument, if any
|
||||||
|
* @param {Expression | undefined} options the rune's second argument
|
||||||
|
* @param {ComponentContext | Context} context
|
||||||
|
* @returns {Expression | undefined}
|
||||||
|
*/
|
||||||
|
export function get_onchange(options, context) {
|
||||||
|
if (options?.type !== 'ObjectExpression') return;
|
||||||
|
|
||||||
|
const property = options.properties.find(
|
||||||
|
(property) =>
|
||||||
|
property.type === 'Property' &&
|
||||||
|
!property.computed &&
|
||||||
|
property.key.type === 'Identifier' &&
|
||||||
|
property.key.name === 'onchange'
|
||||||
|
);
|
||||||
|
|
||||||
|
if (property === undefined) return;
|
||||||
|
|
||||||
|
return /** @type {Expression} */ (context.visit(/** @type {Property} */ (property).value));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wraps a `$.state(...)` call so `onchange` is registered on the source
|
||||||
|
* @param {Expression} call
|
||||||
|
* @param {Expression | undefined} onchange
|
||||||
|
*/
|
||||||
|
export function with_onchange(call, onchange) {
|
||||||
|
return onchange === undefined ? call : b.call('$.onchange', call, onchange);
|
||||||
|
}
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
import { flushSync } from 'svelte';
|
||||||
|
import { test } from '../../test';
|
||||||
|
|
||||||
|
export default test({
|
||||||
|
async test({ assert, target, logs }) {
|
||||||
|
const [btn, btn2] = target.querySelectorAll('button');
|
||||||
|
|
||||||
|
flushSync(() => btn.click());
|
||||||
|
assert.deepEqual(logs, ['foo', 'baz']);
|
||||||
|
|
||||||
|
flushSync(() => btn2.click());
|
||||||
|
assert.deepEqual(logs, ['foo', 'baz', 'foo', 'baz']);
|
||||||
|
}
|
||||||
|
});
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
<script>
|
||||||
|
let foo = $state({ bar: 1 }, {
|
||||||
|
onchange(){
|
||||||
|
console.log("foo");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
let baz = $state(foo, {
|
||||||
|
onchange(){
|
||||||
|
console.log("baz");
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<button onclick={()=> foo.bar++}>foo</button>
|
||||||
|
<button onclick={()=> baz.bar++}>baz</button>
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
import { flushSync } from 'svelte';
|
||||||
|
import { test } from '../../test';
|
||||||
|
|
||||||
|
export default test({
|
||||||
|
async test({ assert, target, logs }) {
|
||||||
|
const btn = target.querySelector('button');
|
||||||
|
|
||||||
|
flushSync(() => btn?.click());
|
||||||
|
assert.deepEqual(logs, [{ message: 'hello' }, { message: 'goodbye' }]);
|
||||||
|
}
|
||||||
|
});
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
<script>
|
||||||
|
let object = $state(
|
||||||
|
{},
|
||||||
|
{
|
||||||
|
onchange() {
|
||||||
|
console.log($state.snapshot(object));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
object.message = 'hello';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<button onclick={() => object.message = 'goodbye'}>goodbye</button>
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
import { flushSync } from 'svelte';
|
||||||
|
import { test } from '../../test';
|
||||||
|
|
||||||
|
export default test({
|
||||||
|
async test({ assert, target, logs }) {
|
||||||
|
const [btn, btn2] = target.querySelectorAll('button');
|
||||||
|
|
||||||
|
flushSync(() => btn.click());
|
||||||
|
assert.deepEqual(logs, [[{}, {}, {}, {}, {}, {}, {}, {}]]);
|
||||||
|
|
||||||
|
flushSync(() => btn2.click());
|
||||||
|
assert.deepEqual(logs, [[{}, {}, {}, {}, {}, {}, {}, {}], []]);
|
||||||
|
}
|
||||||
|
});
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
<script>
|
||||||
|
let array = $state([], {
|
||||||
|
onchange() {
|
||||||
|
console.log($state.snapshot(array));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- clicking either of these buttons should result in at most one log -->
|
||||||
|
<button onclick={() => array = [{}, {}, {}, {}, {}, {}, {}, {}]}>populate array</button>
|
||||||
|
<button onclick={() => array.length = 0}>clear array</button>
|
||||||
|
|
||||||
|
<!-- without this, nested proxies aren't created -->
|
||||||
|
<pre>{JSON.stringify(array)}</pre>
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
import { flushSync } from 'svelte';
|
||||||
|
import { test } from '../../test';
|
||||||
|
|
||||||
|
export default test({
|
||||||
|
async test({ assert, target, logs }) {
|
||||||
|
const [btn, btn2, btn3] = target.querySelectorAll('button');
|
||||||
|
|
||||||
|
flushSync(() => btn.click());
|
||||||
|
assert.deepEqual(logs, ['arr']);
|
||||||
|
|
||||||
|
flushSync(() => btn2.click());
|
||||||
|
assert.deepEqual(logs, ['arr', 'arr']);
|
||||||
|
|
||||||
|
flushSync(() => btn3.click());
|
||||||
|
assert.deepEqual(logs, ['arr', 'arr', 'arr']);
|
||||||
|
}
|
||||||
|
});
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
<script>
|
||||||
|
let arr = $state([0,1,2], {
|
||||||
|
onchange(){
|
||||||
|
console.log("arr");
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<button onclick={()=> arr.push(arr.length)}>push</button>
|
||||||
|
<button onclick={()=>arr.splice(0, 2)}>splice</button>
|
||||||
|
<button onclick={()=>arr.sort((a,b)=>b-a)}>sort</button>
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
import { flushSync } from 'svelte';
|
||||||
|
import { test } from '../../test';
|
||||||
|
|
||||||
|
export default test({
|
||||||
|
async test({ assert, target, logs }) {
|
||||||
|
const btn = target.querySelector('button');
|
||||||
|
|
||||||
|
flushSync(() => btn?.click());
|
||||||
|
assert.deepEqual(logs, ['b changed']);
|
||||||
|
}
|
||||||
|
});
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
<script>
|
||||||
|
let a = $state({});
|
||||||
|
|
||||||
|
let b = $state({ count: 0 }, {
|
||||||
|
onchange() {
|
||||||
|
console.log('b changed');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
a.b = b;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<button onclick={()=> b.count++}>{b.count}</button>
|
||||||
@ -0,0 +1,64 @@
|
|||||||
|
import { flushSync } from 'svelte';
|
||||||
|
import { test } from '../../test';
|
||||||
|
|
||||||
|
export default test({
|
||||||
|
async test({ assert, target, logs }) {
|
||||||
|
const [btn, btn2, btn3, btn4, btn5, btn6, btn7] = target.querySelectorAll('button');
|
||||||
|
|
||||||
|
assert.deepEqual(logs, [
|
||||||
|
'constructor count',
|
||||||
|
'constructor proxy',
|
||||||
|
'assign in constructor',
|
||||||
|
'assign in constructor proxy'
|
||||||
|
]);
|
||||||
|
|
||||||
|
logs.length = 0;
|
||||||
|
|
||||||
|
flushSync(() => btn.click());
|
||||||
|
assert.deepEqual(logs, ['class count']);
|
||||||
|
|
||||||
|
flushSync(() => btn2.click());
|
||||||
|
assert.deepEqual(logs, ['class count', 'class proxy']);
|
||||||
|
|
||||||
|
flushSync(() => btn3.click());
|
||||||
|
assert.deepEqual(logs, ['class count', 'class proxy', 'class proxy']);
|
||||||
|
|
||||||
|
flushSync(() => btn4.click());
|
||||||
|
assert.deepEqual(logs, [
|
||||||
|
'class count',
|
||||||
|
'class proxy',
|
||||||
|
'class proxy',
|
||||||
|
'declared in constructor'
|
||||||
|
]);
|
||||||
|
|
||||||
|
flushSync(() => btn5.click());
|
||||||
|
assert.deepEqual(logs, [
|
||||||
|
'class count',
|
||||||
|
'class proxy',
|
||||||
|
'class proxy',
|
||||||
|
'declared in constructor',
|
||||||
|
'declared in constructor'
|
||||||
|
]);
|
||||||
|
|
||||||
|
flushSync(() => btn6.click());
|
||||||
|
assert.deepEqual(logs, [
|
||||||
|
'class count',
|
||||||
|
'class proxy',
|
||||||
|
'class proxy',
|
||||||
|
'declared in constructor',
|
||||||
|
'declared in constructor',
|
||||||
|
'declared in constructor proxy'
|
||||||
|
]);
|
||||||
|
|
||||||
|
flushSync(() => btn7.click());
|
||||||
|
assert.deepEqual(logs, [
|
||||||
|
'class count',
|
||||||
|
'class proxy',
|
||||||
|
'class proxy',
|
||||||
|
'declared in constructor',
|
||||||
|
'declared in constructor',
|
||||||
|
'declared in constructor proxy',
|
||||||
|
'declared in constructor proxy'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
});
|
||||||
@ -0,0 +1,68 @@
|
|||||||
|
<script>
|
||||||
|
class Test{
|
||||||
|
count = $state(0, {
|
||||||
|
onchange(){
|
||||||
|
console.log("class count");
|
||||||
|
}
|
||||||
|
})
|
||||||
|
proxy = $state({count: 0}, {
|
||||||
|
onchange(){
|
||||||
|
console.log("class proxy");
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
#in_constructor = $state(0, {
|
||||||
|
onchange(){
|
||||||
|
console.log("constructor count");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
#in_constructor_proxy = $state({ count: 0 }, {
|
||||||
|
onchange(){
|
||||||
|
console.log("constructor proxy");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
declared_in_constructor;
|
||||||
|
declared_in_constructor_proxy;
|
||||||
|
#assign_in_constructor;
|
||||||
|
#assign_in_constructor_proxy;
|
||||||
|
|
||||||
|
constructor(){
|
||||||
|
this.#in_constructor = 42;
|
||||||
|
this.#in_constructor_proxy.count++;
|
||||||
|
this.declared_in_constructor = $state(0, {
|
||||||
|
onchange(){
|
||||||
|
console.log("declared in constructor");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.declared_in_constructor_proxy = $state({ count: 0 }, {
|
||||||
|
onchange(){
|
||||||
|
console.log("declared in constructor proxy");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.#assign_in_constructor = $state(0, {
|
||||||
|
onchange(){
|
||||||
|
console.log("assign in constructor");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.#assign_in_constructor++;
|
||||||
|
this.#assign_in_constructor_proxy = $state({ count: 0 }, {
|
||||||
|
onchange(){
|
||||||
|
console.log("assign in constructor proxy");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.#assign_in_constructor_proxy.count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const class_test = new Test();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<button onclick={()=> class_test.count++}>{class_test.count}</button>
|
||||||
|
<button onclick={()=> class_test.proxy.count++}>{class_test.proxy.count}</button>
|
||||||
|
<button onclick={()=> class_test.proxy = {count: class_test.proxy.count+1}}>{class_test.proxy.count}</button>
|
||||||
|
<button onclick={()=> class_test.declared_in_constructor++}>{class_test.declared_in_constructor}</button>
|
||||||
|
<button onclick={()=> class_test.declared_in_constructor = class_test.declared_in_constructor + 1 }>{class_test.declared_in_constructor}</button>
|
||||||
|
<button onclick={()=> class_test.declared_in_constructor_proxy.count++}>{class_test.declared_in_constructor_proxy.count}</button>
|
||||||
|
<button onclick={()=> class_test.declared_in_constructor_proxy.count = class_test.declared_in_constructor_proxy.count + 1 }>{class_test.declared_in_constructor_proxy.count}</button>
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
import { flushSync } from 'svelte';
|
||||||
|
import { test } from '../../test';
|
||||||
|
|
||||||
|
export default test({
|
||||||
|
async test({ assert, target, logs }) {
|
||||||
|
const [btn, btn2, btn3, btn4, btn5, btn6] = target.querySelectorAll('button');
|
||||||
|
logs.length = 0;
|
||||||
|
|
||||||
|
flushSync(() => btn.click());
|
||||||
|
flushSync(() => btn2.click());
|
||||||
|
flushSync(() => btn3.click());
|
||||||
|
flushSync(() => btn4.click());
|
||||||
|
flushSync(() => btn5.click());
|
||||||
|
assert.deepEqual(logs, []);
|
||||||
|
|
||||||
|
flushSync(() => btn6.click());
|
||||||
|
flushSync(() => btn.click());
|
||||||
|
assert.deepEqual(logs, ['arr', 'arr']);
|
||||||
|
}
|
||||||
|
});
|
||||||
@ -0,0 +1,43 @@
|
|||||||
|
<script>
|
||||||
|
let arr = $state([{ count: 1 }, { count: 1 }], {
|
||||||
|
onchange(){
|
||||||
|
console.log("arr");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const item = arr.pop();
|
||||||
|
|
||||||
|
const item_2 = arr[0];
|
||||||
|
|
||||||
|
arr[0] = { count: 1 };
|
||||||
|
|
||||||
|
let obj = $state({ value: { count: 0 }, key: { count: 0 } }, {
|
||||||
|
onchange(){
|
||||||
|
console.log("obj");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const item_3 = obj.value;
|
||||||
|
delete obj.value;
|
||||||
|
|
||||||
|
const values = [...Object.values(obj)];
|
||||||
|
|
||||||
|
delete obj.key;
|
||||||
|
|
||||||
|
let arr_2 = $state([{ count: 1 }, { count: 1 }], {
|
||||||
|
onchange(){
|
||||||
|
console.log("arr_2");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const item_4 = arr_2[0];
|
||||||
|
|
||||||
|
arr_2.length = 0;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<button onclick={()=> item.count++}>{item.count}</button>
|
||||||
|
<button onclick={()=> item_2.count++}>{item_2.count}</button>
|
||||||
|
<button onclick={()=> item_3.count++}>{item_3.count}</button>
|
||||||
|
<button onclick={()=> values[0].count++}>{values[0].count}</button>
|
||||||
|
<button onclick={()=> item_4.count++}>{item_4.count}</button>
|
||||||
|
<button onclick={()=> arr.push(item)}>push</button>
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
import { flushSync } from 'svelte';
|
||||||
|
import { test } from '../../test';
|
||||||
|
|
||||||
|
export default test({
|
||||||
|
async test({ assert, target, logs }) {
|
||||||
|
const [btn, btn2] = target.querySelectorAll('button');
|
||||||
|
|
||||||
|
flushSync(() => btn.click());
|
||||||
|
assert.deepEqual(logs, ['proxy']);
|
||||||
|
|
||||||
|
flushSync(() => btn2.click());
|
||||||
|
assert.deepEqual(logs, ['proxy', 'proxy']);
|
||||||
|
}
|
||||||
|
});
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
<script>
|
||||||
|
let proxy = $state({count: 0}, {
|
||||||
|
onchange(){
|
||||||
|
console.log("proxy");
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<button onclick={()=> proxy.count++}>{proxy.count}</button>
|
||||||
|
<button onclick={()=> proxy = {count: proxy.count+1}}>{proxy.count}</button>
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
import { flushSync } from 'svelte';
|
||||||
|
import { test } from '../../test';
|
||||||
|
|
||||||
|
export default test({
|
||||||
|
async test({ assert, target, logs }) {
|
||||||
|
const [btn, btn2, btn3, btn4] = target.querySelectorAll('button');
|
||||||
|
|
||||||
|
flushSync(() => btn.click());
|
||||||
|
assert.deepEqual(logs, ['a']);
|
||||||
|
|
||||||
|
flushSync(() => btn2.click());
|
||||||
|
assert.deepEqual(logs, ['a', 'b', 'c']);
|
||||||
|
flushSync(() => btn3.click());
|
||||||
|
assert.deepEqual(logs, ['a', 'b', 'c', 'b', 'c']);
|
||||||
|
flushSync(() => btn4.click());
|
||||||
|
assert.deepEqual(logs, ['a', 'b', 'c', 'b', 'c', 'c']);
|
||||||
|
flushSync(() => btn2.click());
|
||||||
|
assert.deepEqual(logs, ['a', 'b', 'c', 'b', 'c', 'c', 'b']);
|
||||||
|
}
|
||||||
|
});
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
<script>
|
||||||
|
let obj = { count: 0 };
|
||||||
|
|
||||||
|
let a = $state(obj, {
|
||||||
|
onchange() {
|
||||||
|
console.log('a');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let b = $state(obj, {
|
||||||
|
onchange() {
|
||||||
|
console.log('b');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let c = $state(b, {
|
||||||
|
onchange() {
|
||||||
|
console.log('c');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<button onclick={()=> a.count++}>{a.count}</button>
|
||||||
|
<button onclick={()=> b.count++}>{b.count}</button>
|
||||||
|
<button onclick={()=> c.count++}>{c.count}</button>
|
||||||
|
|
||||||
|
<button onclick={() => c = { count: c.count }}>unlink</button>
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
import { flushSync } from 'svelte';
|
||||||
|
import { test } from '../../test';
|
||||||
|
|
||||||
|
export default test({
|
||||||
|
async test({ assert, target, logs }) {
|
||||||
|
const [count, items] = target.querySelectorAll('button');
|
||||||
|
|
||||||
|
flushSync(() => count.click());
|
||||||
|
assert.deepEqual(logs, ['count', 20]);
|
||||||
|
assert.htmlEqual(count.innerHTML, '10');
|
||||||
|
|
||||||
|
logs.length = 0;
|
||||||
|
flushSync(() => items.click());
|
||||||
|
assert.deepEqual(logs, ['items', 3]);
|
||||||
|
assert.htmlEqual(items.innerHTML, '2');
|
||||||
|
}
|
||||||
|
});
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
<script>
|
||||||
|
let count = $state(0, {
|
||||||
|
onchange() {
|
||||||
|
console.log('count', count);
|
||||||
|
count = Math.min(count, 10);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let items = $state([], {
|
||||||
|
onchange() {
|
||||||
|
console.log('items', items.length);
|
||||||
|
if (items.length > 2) items.length = 2;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<button onclick={() => (count = 20)}>{count}</button>
|
||||||
|
<button onclick={() => items.push(1, 2, 3)}>{items.length}</button>
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
import { flushSync } from 'svelte';
|
||||||
|
import { test } from '../../test';
|
||||||
|
|
||||||
|
export default test({
|
||||||
|
async test({ assert, target, logs }) {
|
||||||
|
const btn = target.querySelector('button');
|
||||||
|
|
||||||
|
flushSync(() => btn?.click());
|
||||||
|
assert.deepEqual(logs, ['count']);
|
||||||
|
}
|
||||||
|
});
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
<script>
|
||||||
|
let count = $state(0, {
|
||||||
|
onchange(){
|
||||||
|
console.log("count");
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<button onclick={()=> count++}>{count}</button>
|
||||||
@ -0,0 +1,106 @@
|
|||||||
|
import { flushSync } from 'svelte';
|
||||||
|
import { test } from '../../test';
|
||||||
|
|
||||||
|
export default test({
|
||||||
|
async test({ assert, target, logs }) {
|
||||||
|
const [btn, btn2, btn3, btn4, btn5, btn6, btn7, btn8, btn9, btn10, btn11, btn12, btn13] =
|
||||||
|
target.querySelectorAll('button');
|
||||||
|
|
||||||
|
assert.deepEqual(logs, [
|
||||||
|
'constructor count',
|
||||||
|
'constructor object',
|
||||||
|
'assign in constructor',
|
||||||
|
'assign in constructor object'
|
||||||
|
]);
|
||||||
|
|
||||||
|
logs.length = 0;
|
||||||
|
|
||||||
|
flushSync(() => btn.click());
|
||||||
|
assert.deepEqual(logs, ['count']);
|
||||||
|
|
||||||
|
flushSync(() => btn2.click());
|
||||||
|
assert.deepEqual(logs, ['count']);
|
||||||
|
|
||||||
|
flushSync(() => btn3.click());
|
||||||
|
assert.deepEqual(logs, ['count', 'object']);
|
||||||
|
|
||||||
|
flushSync(() => btn4.click());
|
||||||
|
assert.deepEqual(logs, ['count', 'object', 'class count']);
|
||||||
|
|
||||||
|
flushSync(() => btn5.click());
|
||||||
|
assert.deepEqual(logs, ['count', 'object', 'class count']);
|
||||||
|
|
||||||
|
flushSync(() => btn6.click());
|
||||||
|
assert.deepEqual(logs, ['count', 'object', 'class count', 'class object']);
|
||||||
|
|
||||||
|
flushSync(() => btn7.click());
|
||||||
|
assert.deepEqual(logs, [
|
||||||
|
'count',
|
||||||
|
'object',
|
||||||
|
'class count',
|
||||||
|
'class object',
|
||||||
|
'declared in constructor'
|
||||||
|
]);
|
||||||
|
|
||||||
|
flushSync(() => btn8.click());
|
||||||
|
assert.deepEqual(logs, [
|
||||||
|
'count',
|
||||||
|
'object',
|
||||||
|
'class count',
|
||||||
|
'class object',
|
||||||
|
'declared in constructor',
|
||||||
|
'declared in constructor object'
|
||||||
|
]);
|
||||||
|
|
||||||
|
flushSync(() => btn9.click());
|
||||||
|
assert.deepEqual(logs, [
|
||||||
|
'count',
|
||||||
|
'object',
|
||||||
|
'class count',
|
||||||
|
'class object',
|
||||||
|
'declared in constructor',
|
||||||
|
'declared in constructor object'
|
||||||
|
]);
|
||||||
|
|
||||||
|
flushSync(() => btn10.click());
|
||||||
|
assert.deepEqual(logs, [
|
||||||
|
'count',
|
||||||
|
'object',
|
||||||
|
'class count',
|
||||||
|
'class object',
|
||||||
|
'declared in constructor',
|
||||||
|
'declared in constructor object'
|
||||||
|
]);
|
||||||
|
|
||||||
|
flushSync(() => btn11.click());
|
||||||
|
assert.deepEqual(logs, [
|
||||||
|
'count',
|
||||||
|
'object',
|
||||||
|
'class count',
|
||||||
|
'class object',
|
||||||
|
'declared in constructor',
|
||||||
|
'declared in constructor object'
|
||||||
|
]);
|
||||||
|
|
||||||
|
flushSync(() => btn12.click());
|
||||||
|
assert.deepEqual(logs, [
|
||||||
|
'count',
|
||||||
|
'object',
|
||||||
|
'class count',
|
||||||
|
'class object',
|
||||||
|
'declared in constructor',
|
||||||
|
'declared in constructor object'
|
||||||
|
]);
|
||||||
|
|
||||||
|
flushSync(() => btn13.click());
|
||||||
|
assert.deepEqual(logs, [
|
||||||
|
'count',
|
||||||
|
'object',
|
||||||
|
'class count',
|
||||||
|
'class object',
|
||||||
|
'declared in constructor',
|
||||||
|
'declared in constructor object',
|
||||||
|
'arr'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
});
|
||||||
@ -0,0 +1,94 @@
|
|||||||
|
<script>
|
||||||
|
let count = $state.raw(0, {
|
||||||
|
onchange(){
|
||||||
|
console.log("count");
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
let object = $state.raw({count: 0}, {
|
||||||
|
onchange(){
|
||||||
|
console.log("object");
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
class Test{
|
||||||
|
count = $state.raw(0, {
|
||||||
|
onchange(){
|
||||||
|
console.log("class count");
|
||||||
|
}
|
||||||
|
})
|
||||||
|
object = $state.raw({count: 0}, {
|
||||||
|
onchange(){
|
||||||
|
console.log("class object");
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
#in_constructor = $state.raw(0, {
|
||||||
|
onchange(){
|
||||||
|
console.log("constructor count");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
#in_constructor_obj = $state.raw({ count: 0 }, {
|
||||||
|
onchange(){
|
||||||
|
console.log("constructor object");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
declared_in_constructor;
|
||||||
|
declared_in_constructor_obj;
|
||||||
|
#assign_in_constructor;
|
||||||
|
#assign_in_constructor_obj;
|
||||||
|
|
||||||
|
constructor(){
|
||||||
|
this.#in_constructor++;
|
||||||
|
this.#in_constructor_obj = { count: this.#in_constructor_obj.count + 1 };
|
||||||
|
this.declared_in_constructor = $state.raw(0, {
|
||||||
|
onchange(){
|
||||||
|
console.log("declared in constructor");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.declared_in_constructor_obj = $state.raw({ count: 0 }, {
|
||||||
|
onchange(){
|
||||||
|
console.log("declared in constructor object");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.#assign_in_constructor = $state.raw(0, {
|
||||||
|
onchange(){
|
||||||
|
console.log("assign in constructor");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.#assign_in_constructor++;
|
||||||
|
this.#assign_in_constructor_obj = $state.raw({ count: 0 }, {
|
||||||
|
onchange(){
|
||||||
|
console.log("assign in constructor object");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.#assign_in_constructor_obj = { count: this.#assign_in_constructor_obj.count + 1 };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const class_test = new Test();
|
||||||
|
|
||||||
|
let arr = $state.raw([0,1,2], {
|
||||||
|
onchange(){
|
||||||
|
console.log("arr");
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<button onclick={()=> count++}>{count}</button>
|
||||||
|
<button onclick={()=> object.count++}>{object.count}</button>
|
||||||
|
<button onclick={()=> object = {count: object.count+1}}>{object.count}</button>
|
||||||
|
|
||||||
|
<button onclick={()=> class_test.count++}>{class_test.count}</button>
|
||||||
|
<button onclick={()=> class_test.object.count++}>{class_test.object.count}</button>
|
||||||
|
<button onclick={()=> class_test.object = {count: class_test.object.count+1}}>{class_test.object.count}</button>
|
||||||
|
<button onclick={()=> class_test.declared_in_constructor++}>{class_test.declared_in_constructor}</button>
|
||||||
|
<button onclick={()=> class_test.declared_in_constructor_obj = {count: class_test.declared_in_constructor_obj.count + 1}}>{class_test.declared_in_constructor_obj.count}</button>
|
||||||
|
<button onclick={()=> class_test.declared_in_constructor_obj.count++}>{class_test.declared_in_constructor_obj.count}</button>
|
||||||
|
|
||||||
|
<button onclick={()=> arr.push(arr.length)}>push</button>
|
||||||
|
<button onclick={()=>arr.splice(0, 2)}>splice</button>
|
||||||
|
<button onclick={()=>arr.sort((a,b)=>b-a)}>sort</button>
|
||||||
|
<button onclick={()=>arr = []}>assign</button>
|
||||||
Loading…
Reference in new issue