Skip to content

Commit 8a7e540

Browse files
committed
fix: handle component binding mutation
#10359 (comment)
1 parent 2cb78ac commit 8a7e540

File tree

5 files changed

+57
-1
lines changed

5 files changed

+57
-1
lines changed

.changeset/witty-readers-provide.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"svelte": patch
3+
---
4+
5+
fix: handle component binding mutation

packages/svelte/src/internal/client/reactivity/props.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,10 +175,13 @@ export function prop(props, key, flags, initial) {
175175
// intermediate mode — prop is written to, but the parent component had
176176
// `bind:foo` which means we can just call `$$props.foo = value` directly
177177
if (setter) {
178-
return function (/** @type {V} */ value) {
178+
return function (/** @type {V} */ value, mutation = false) {
179179
if (arguments.length === 1) {
180180
/** @type {Function} */ (setter)(value);
181181
return value;
182+
} else if (mutation) {
183+
/** @type {Function} */ (setter)(getter());
184+
return value;
182185
} else {
183186
return getter();
184187
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<script>
2+
export let value;
3+
</script>
4+
5+
<input bind:value={value.name}>
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { ok, test } from '../../test';
2+
3+
export default test({
4+
html: `
5+
<input>
6+
<p>foo</p>
7+
`,
8+
9+
ssrHtml: `
10+
<input value=foo>
11+
<p>foo</p>
12+
`,
13+
14+
async test({ assert, component, target, window }) {
15+
const event = new window.MouseEvent('input');
16+
const input = target.querySelector('input');
17+
ok(input);
18+
19+
input.value = 'blah';
20+
await input.dispatchEvent(event);
21+
await Promise.resolve();
22+
23+
assert.deepEqual(component.deep, { name: 'blah' });
24+
assert.htmlEqual(
25+
target.innerHTML,
26+
`
27+
<input>
28+
<p>blah</p>
29+
`
30+
);
31+
}
32+
});
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<script>
2+
import Widget from './Widget.svelte';
3+
4+
export let deep = {
5+
name: 'foo'
6+
};
7+
</script>
8+
9+
<Widget bind:value={deep}/>
10+
11+
<p>{deep.name}</p>

0 commit comments

Comments
 (0)