Skip to content

Commit c2f5964

Browse files
fix(ssr): handle v-bind modifiers during render attrs (#14263)
close #14262
1 parent 3c8b2fc commit c2f5964

File tree

2 files changed

+24
-2
lines changed

2 files changed

+24
-2
lines changed

packages/server-renderer/__tests__/render.spec.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1229,5 +1229,23 @@ function testRender(type: string, render: typeof renderToString) {
12291229
// during the render phase
12301230
expect(getterSpy).toHaveBeenCalledTimes(2)
12311231
})
1232+
1233+
test('props modifiers in render attrs', async () => {
1234+
const app = createApp({
1235+
setup() {
1236+
return () =>
1237+
h(
1238+
'div',
1239+
{
1240+
'^attr': 'attr',
1241+
'.prop': 'prop',
1242+
},
1243+
'Functional Component',
1244+
)
1245+
},
1246+
})
1247+
const html = await render(app)
1248+
expect(html).toBe(`<div attr="attr">Functional Component</div>`)
1249+
})
12321250
})
12331251
}

packages/server-renderer/src/helpers/ssrRenderAttrs.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,19 @@ export function ssrRenderAttrs(
2929
tag?: string,
3030
): string {
3131
let ret = ''
32-
for (const key in props) {
32+
for (let key in props) {
3333
if (
3434
shouldIgnoreProp(key) ||
3535
isOn(key) ||
36-
(tag === 'textarea' && key === 'value')
36+
(tag === 'textarea' && key === 'value') ||
37+
// force as property (not rendered in SSR)
38+
key.startsWith('.')
3739
) {
3840
continue
3941
}
4042
const value = props[key]
43+
// force as attribute
44+
if (key.startsWith('^')) key = key.slice(1)
4145
if (key === 'class' || key === 'className') {
4246
ret += ` class="${ssrRenderClass(value)}"`
4347
} else if (key === 'style') {

0 commit comments

Comments
 (0)