_push(\`</optgroup></select></div>\`)
}"
`)
+
+ expect(
+ compileWithWrapper(`
+ <select multiple v-model="model">
+ <optgroup>
+ <option v-for="item in items" :value="item">{{item}}</option>
+ </optgroup>
+ </select>`).code,
+ ).toMatchInlineSnapshot(`
+ "const { ssrRenderAttr: _ssrRenderAttr, ssrIncludeBooleanAttr: _ssrIncludeBooleanAttr, ssrLooseContain: _ssrLooseContain, ssrLooseEqual: _ssrLooseEqual, ssrRenderAttrs: _ssrRenderAttrs, ssrInterpolate: _ssrInterpolate, ssrRenderList: _ssrRenderList } = require("vue/server-renderer")
+
+ return function ssrRender(_ctx, _push, _parent, _attrs) {
+ _push(\`<div\${_ssrRenderAttrs(_attrs)}><select multiple><optgroup><!--[-->\`)
+ _ssrRenderList(_ctx.items, (item) => {
+ _push(\`<option\${
+ _ssrRenderAttr("value", item)
+ }\${
+ (_ssrIncludeBooleanAttr((Array.isArray(_ctx.model))
+ ? _ssrLooseContain(_ctx.model, item)
+ : _ssrLooseEqual(_ctx.model, item))) ? " selected" : ""
+ }>\${
+ _ssrInterpolate(item)
+ }</option>\`)
+ })
+ _push(\`<!--]--></optgroup></select></div>\`)
+ }"
+ `)
+
+ expect(
+ compileWithWrapper(`
+ <select multiple v-model="model">
+ <optgroup>
+ <option v-if="true" :value="item">{{item}}</option>
+ </optgroup>
+ </select>`).code,
+ ).toMatchInlineSnapshot(`
+ "const { ssrRenderAttr: _ssrRenderAttr, ssrIncludeBooleanAttr: _ssrIncludeBooleanAttr, ssrLooseContain: _ssrLooseContain, ssrLooseEqual: _ssrLooseEqual, ssrRenderAttrs: _ssrRenderAttrs, ssrInterpolate: _ssrInterpolate } = require("vue/server-renderer")
+
+ return function ssrRender(_ctx, _push, _parent, _attrs) {
+ _push(\`<div\${_ssrRenderAttrs(_attrs)}><select multiple><optgroup>\`)
+ if (true) {
+ _push(\`<option\${
+ _ssrRenderAttr("value", _ctx.item)
+ }\${
+ (_ssrIncludeBooleanAttr((Array.isArray(_ctx.model))
+ ? _ssrLooseContain(_ctx.model, _ctx.item)
+ : _ssrLooseEqual(_ctx.model, _ctx.item))) ? " selected" : ""
+ }>\${
+ _ssrInterpolate(_ctx.item)
+ }</option>\`)
+ } else {
+ _push(\`<!---->\`)
+ }
+ _push(\`</optgroup></select></div>\`)
+ }"
+ `)
+
+ expect(
+ compileWithWrapper(`
+ <select multiple v-model="model">
+ <optgroup>
+ <template v-if="ok">
+ <option v-for="item in items" :value="item">{{item}}</option>
+ </template>
+ </optgroup>
+ </select>`).code,
+ ).toMatchInlineSnapshot(`
+ "const { ssrRenderAttr: _ssrRenderAttr, ssrIncludeBooleanAttr: _ssrIncludeBooleanAttr, ssrLooseContain: _ssrLooseContain, ssrLooseEqual: _ssrLooseEqual, ssrRenderAttrs: _ssrRenderAttrs, ssrInterpolate: _ssrInterpolate, ssrRenderList: _ssrRenderList } = require("vue/server-renderer")
+
+ return function ssrRender(_ctx, _push, _parent, _attrs) {
+ _push(\`<div\${_ssrRenderAttrs(_attrs)}><select multiple><optgroup>\`)
+ if (_ctx.ok) {
+ _push(\`<!--[-->\`)
+ _ssrRenderList(_ctx.items, (item) => {
+ _push(\`<option\${
+ _ssrRenderAttr("value", item)
+ }\${
+ (_ssrIncludeBooleanAttr((Array.isArray(_ctx.model))
+ ? _ssrLooseContain(_ctx.model, item)
+ : _ssrLooseEqual(_ctx.model, item))) ? " selected" : ""
+ }>\${
+ _ssrInterpolate(item)
+ }</option>\`)
+ })
+ _push(\`<!--]-->\`)
+ } else {
+ _push(\`<!---->\`)
+ }
+ _push(\`</optgroup></select></div>\`)
+ }"
+ `)
+
+ expect(
+ compileWithWrapper(`
+ <select multiple v-model="model">
+ <optgroup>
+ <template v-for="item in items" :value="item">
+ <option v-if="item===1" :value="item">{{item}}</option>
+ </template>
+ </optgroup>
+ </select>`).code,
+ ).toMatchInlineSnapshot(`
+ "const { ssrRenderAttr: _ssrRenderAttr, ssrIncludeBooleanAttr: _ssrIncludeBooleanAttr, ssrLooseContain: _ssrLooseContain, ssrLooseEqual: _ssrLooseEqual, ssrRenderAttrs: _ssrRenderAttrs, ssrInterpolate: _ssrInterpolate, ssrRenderList: _ssrRenderList } = require("vue/server-renderer")
+
+ return function ssrRender(_ctx, _push, _parent, _attrs) {
+ _push(\`<div\${_ssrRenderAttrs(_attrs)}><select multiple><optgroup><!--[-->\`)
+ _ssrRenderList(_ctx.items, (item) => {
+ _push(\`<!--[-->\`)
+ if (item===1) {
+ _push(\`<option\${
+ _ssrRenderAttr("value", item)
+ }\${
+ (_ssrIncludeBooleanAttr((Array.isArray(_ctx.model))
+ ? _ssrLooseContain(_ctx.model, item)
+ : _ssrLooseEqual(_ctx.model, item))) ? " selected" : ""
+ }>\${
+ _ssrInterpolate(item)
+ }</option>\`)
+ } else {
+ _push(\`<!---->\`)
+ }
+ _push(\`<!--]-->\`)
+ })
+ _push(\`<!--]--></optgroup></select></div>\`)
+ }"
+ `)
})
test('<input type="radio">', () => {
}
}
+ const processSelectChildren = (children: TemplateChildNode[]) => {
+ children.forEach(child => {
+ if (child.type === NodeTypes.ELEMENT) {
+ processOption(child as PlainElementNode)
+ } else if (child.type === NodeTypes.FOR) {
+ processSelectChildren(child.children)
+ } else if (child.type === NodeTypes.IF) {
+ child.branches.forEach(b => processSelectChildren(b.children))
+ }
+ })
+ }
+
function processOption(plainNode: PlainElementNode) {
if (plainNode.tag === 'option') {
if (plainNode.props.findIndex(p => p.name === 'selected') === -1) {
)
}
} else if (plainNode.tag === 'optgroup') {
- plainNode.children.forEach(option =>
- processOption(option as PlainElementNode),
- )
+ processSelectChildren(plainNode.children)
}
}
checkDuplicatedValue()
node.children = [createInterpolation(model, model.loc)]
} else if (node.tag === 'select') {
- 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)
+ processSelectChildren(node.children)
} else {
context.onError(
createDOMCompilerError(