Skip to content

Commit 4f8d807

Browse files
authoredNov 15, 2024··
fix(ssr): handle initial selected state for select with v-model + v-for option (#12399)
close #12395
1 parent 983eb50 commit 4f8d807

File tree

2 files changed

+59
-5
lines changed

2 files changed

+59
-5
lines changed
 

‎packages/compiler-ssr/__tests__/ssrVModel.spec.ts

+46
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,52 @@ describe('ssr: v-model', () => {
5252
}"
5353
`)
5454

55+
expect(
56+
compileWithWrapper(
57+
`<select v-model="model"><option v-for="i in items" :value="i"></option></select>`,
58+
).code,
59+
).toMatchInlineSnapshot(`
60+
"const { ssrRenderAttr: _ssrRenderAttr, ssrIncludeBooleanAttr: _ssrIncludeBooleanAttr, ssrLooseContain: _ssrLooseContain, ssrLooseEqual: _ssrLooseEqual, ssrRenderAttrs: _ssrRenderAttrs, ssrRenderList: _ssrRenderList } = require("vue/server-renderer")
61+
62+
return function ssrRender(_ctx, _push, _parent, _attrs) {
63+
_push(\`<div\${_ssrRenderAttrs(_attrs)}><select><!--[-->\`)
64+
_ssrRenderList(_ctx.items, (i) => {
65+
_push(\`<option\${
66+
_ssrRenderAttr("value", i)
67+
}\${
68+
(_ssrIncludeBooleanAttr((Array.isArray(_ctx.model))
69+
? _ssrLooseContain(_ctx.model, i)
70+
: _ssrLooseEqual(_ctx.model, i))) ? " selected" : ""
71+
}></option>\`)
72+
})
73+
_push(\`<!--]--></select></div>\`)
74+
}"
75+
`)
76+
77+
expect(
78+
compileWithWrapper(
79+
`<select v-model="model"><option v-if="true" :value="i"></option></select>`,
80+
).code,
81+
).toMatchInlineSnapshot(`
82+
"const { ssrRenderAttr: _ssrRenderAttr, ssrIncludeBooleanAttr: _ssrIncludeBooleanAttr, ssrLooseContain: _ssrLooseContain, ssrLooseEqual: _ssrLooseEqual, ssrRenderAttrs: _ssrRenderAttrs } = require("vue/server-renderer")
83+
84+
return function ssrRender(_ctx, _push, _parent, _attrs) {
85+
_push(\`<div\${_ssrRenderAttrs(_attrs)}><select>\`)
86+
if (true) {
87+
_push(\`<option\${
88+
_ssrRenderAttr("value", _ctx.i)
89+
}\${
90+
(_ssrIncludeBooleanAttr((Array.isArray(_ctx.model))
91+
? _ssrLooseContain(_ctx.model, _ctx.i)
92+
: _ssrLooseEqual(_ctx.model, _ctx.i))) ? " selected" : ""
93+
}></option>\`)
94+
} else {
95+
_push(\`<!---->\`)
96+
}
97+
_push(\`</select></div>\`)
98+
}"
99+
`)
100+
55101
expect(
56102
compileWithWrapper(
57103
`<select multiple v-model="model"><option value="1" selected></option><option value="2"></option></select>`,

‎packages/compiler-ssr/src/transforms/ssrVModel.ts

+13-5
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
type ExpressionNode,
66
NodeTypes,
77
type PlainElementNode,
8+
type TemplateChildNode,
89
createCallExpression,
910
createConditionalExpression,
1011
createDOMCompilerError,
@@ -162,11 +163,18 @@ export const ssrTransformModel: DirectiveTransform = (dir, node, context) => {
162163
checkDuplicatedValue()
163164
node.children = [createInterpolation(model, model.loc)]
164165
} else if (node.tag === 'select') {
165-
node.children.forEach(child => {
166-
if (child.type === NodeTypes.ELEMENT) {
167-
processOption(child as PlainElementNode)
168-
}
169-
})
166+
const processChildren = (children: TemplateChildNode[]) => {
167+
children.forEach(child => {
168+
if (child.type === NodeTypes.ELEMENT) {
169+
processOption(child as PlainElementNode)
170+
} else if (child.type === NodeTypes.FOR) {
171+
processChildren(child.children)
172+
} else if (child.type === NodeTypes.IF) {
173+
child.branches.forEach(b => processChildren(b.children))
174+
}
175+
})
176+
}
177+
processChildren(node.children)
170178
} else {
171179
context.onError(
172180
createDOMCompilerError(

0 commit comments

Comments
 (0)
Please sign in to comment.