Skip to content

Commit

Permalink
fix(ssr): handle initial selected state for select with v-model + v-f…
Browse files Browse the repository at this point in the history
…or option (#12399)

close #12395
  • Loading branch information
edison1105 authored Nov 15, 2024
1 parent 983eb50 commit 4f8d807
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 5 deletions.
46 changes: 46 additions & 0 deletions packages/compiler-ssr/__tests__/ssrVModel.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,52 @@ describe('ssr: v-model', () => {
}"
`)

expect(
compileWithWrapper(
`<select v-model="model"><option v-for="i in items" :value="i"></option></select>`,
).code,
).toMatchInlineSnapshot(`
"const { ssrRenderAttr: _ssrRenderAttr, ssrIncludeBooleanAttr: _ssrIncludeBooleanAttr, ssrLooseContain: _ssrLooseContain, ssrLooseEqual: _ssrLooseEqual, ssrRenderAttrs: _ssrRenderAttrs, ssrRenderList: _ssrRenderList } = require("vue/server-renderer")
return function ssrRender(_ctx, _push, _parent, _attrs) {
_push(\`<div\${_ssrRenderAttrs(_attrs)}><select><!--[-->\`)
_ssrRenderList(_ctx.items, (i) => {
_push(\`<option\${
_ssrRenderAttr("value", i)
}\${
(_ssrIncludeBooleanAttr((Array.isArray(_ctx.model))
? _ssrLooseContain(_ctx.model, i)
: _ssrLooseEqual(_ctx.model, i))) ? " selected" : ""
}></option>\`)
})
_push(\`<!--]--></select></div>\`)
}"
`)

expect(
compileWithWrapper(
`<select v-model="model"><option v-if="true" :value="i"></option></select>`,
).code,
).toMatchInlineSnapshot(`
"const { ssrRenderAttr: _ssrRenderAttr, ssrIncludeBooleanAttr: _ssrIncludeBooleanAttr, ssrLooseContain: _ssrLooseContain, ssrLooseEqual: _ssrLooseEqual, ssrRenderAttrs: _ssrRenderAttrs } = require("vue/server-renderer")
return function ssrRender(_ctx, _push, _parent, _attrs) {
_push(\`<div\${_ssrRenderAttrs(_attrs)}><select>\`)
if (true) {
_push(\`<option\${
_ssrRenderAttr("value", _ctx.i)
}\${
(_ssrIncludeBooleanAttr((Array.isArray(_ctx.model))
? _ssrLooseContain(_ctx.model, _ctx.i)
: _ssrLooseEqual(_ctx.model, _ctx.i))) ? " selected" : ""
}></option>\`)
} else {
_push(\`<!---->\`)
}
_push(\`</select></div>\`)
}"
`)

expect(
compileWithWrapper(
`<select multiple v-model="model"><option value="1" selected></option><option value="2"></option></select>`,
Expand Down
18 changes: 13 additions & 5 deletions packages/compiler-ssr/src/transforms/ssrVModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
type ExpressionNode,
NodeTypes,
type PlainElementNode,
type TemplateChildNode,
createCallExpression,
createConditionalExpression,
createDOMCompilerError,
Expand Down Expand Up @@ -162,11 +163,18 @@ export const ssrTransformModel: DirectiveTransform = (dir, node, context) => {
checkDuplicatedValue()
node.children = [createInterpolation(model, model.loc)]
} else if (node.tag === 'select') {
node.children.forEach(child => {
if (child.type === NodeTypes.ELEMENT) {
processOption(child as PlainElementNode)
}
})
const processChildren = (children: TemplateChildNode[]) => {
children.forEach(child => {
if (child.type === NodeTypes.ELEMENT) {
processOption(child as PlainElementNode)
} else if (child.type === NodeTypes.FOR) {
processChildren(child.children)
} else if (child.type === NodeTypes.IF) {
child.branches.forEach(b => processChildren(b.children))
}
})
}
processChildren(node.children)
} else {
context.onError(
createDOMCompilerError(
Expand Down

0 comments on commit 4f8d807

Please sign in to comment.