fix(ssr): handle initial selected state for select with v-model + v-for option

This commit is contained in:
daiwei 2024-11-15 10:02:00 +08:00
parent a49858f3ee
commit 3b2f5e67b1
2 changed files with 33 additions and 5 deletions

View File

@ -52,6 +52,28 @@ 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 multiple v-model="model"><option value="1" selected></option><option value="2"></option></select>`,

View File

@ -5,6 +5,7 @@ import {
type ExpressionNode,
NodeTypes,
type PlainElementNode,
type TemplateChildNode,
createCallExpression,
createConditionalExpression,
createDOMCompilerError,
@ -162,11 +163,16 @@ 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)
}
})
}
processChildren(node.children)
} else {
context.onError(
createDOMCompilerError(