Skip to content

Commit fe5428d

Browse files
committed
fix(compiler-ssr): handle v-model checkbox with true-value binding
1 parent 48f00c0 commit fe5428d

File tree

3 files changed

+80
-13
lines changed

3 files changed

+80
-13
lines changed

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

+33-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ describe('ssr: v-model', () => {
4949
`)
5050
})
5151

52-
test('<input type="checkbox"', () => {
52+
test('<input type="checkbox">', () => {
5353
expect(compileWithWrapper(`<input type="checkbox" v-model="bar">`).code)
5454
.toMatchInlineSnapshot(`
5555
"const { ssrLooseContain: _ssrLooseContain, ssrRenderAttrs: _ssrRenderAttrs } = require(\\"@vue/server-renderer\\")
@@ -81,6 +81,38 @@ describe('ssr: v-model', () => {
8181
}></div>\`)
8282
}"
8383
`)
84+
85+
expect(
86+
compileWithWrapper(
87+
`<input type="checkbox" :true-value="foo" :false-value="bar" v-model="baz">`
88+
).code
89+
).toMatchInlineSnapshot(`
90+
"const { ssrLooseEqual: _ssrLooseEqual, ssrRenderAttrs: _ssrRenderAttrs } = require(\\"@vue/server-renderer\\")
91+
92+
return function ssrRender(_ctx, _push, _parent, _attrs) {
93+
_push(\`<div\${
94+
_ssrRenderAttrs(_attrs)
95+
}><input type=\\"checkbox\\"\${
96+
(_ssrLooseEqual(_ctx.baz, _ctx.foo)) ? \\" checked\\" : \\"\\"
97+
}></div>\`)
98+
}"
99+
`)
100+
101+
expect(
102+
compileWithWrapper(
103+
`<input type="checkbox" true-value="foo" false-value="bar" v-model="baz">`
104+
).code
105+
).toMatchInlineSnapshot(`
106+
"const { ssrLooseEqual: _ssrLooseEqual, ssrRenderAttrs: _ssrRenderAttrs } = require(\\"@vue/server-renderer\\")
107+
108+
return function ssrRender(_ctx, _push, _parent, _attrs) {
109+
_push(\`<div\${
110+
_ssrRenderAttrs(_attrs)
111+
}><input type=\\"checkbox\\"\${
112+
(_ssrLooseEqual(_ctx.baz, \\"foo\\")) ? \\" checked\\" : \\"\\"
113+
}></div>\`)
114+
}"
115+
`)
84116
})
85117

86118
test('<textarea>', () => {

packages/compiler-ssr/src/transforms/ssrTransformElement.ts

+19-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ import {
2525
isBindKey,
2626
createSequenceExpression,
2727
InterpolationNode,
28-
isStaticExp
28+
isStaticExp,
29+
AttributeNode
2930
} from '@vue/compiler-dom'
3031
import {
3132
escapeHtml,
@@ -159,6 +160,10 @@ export const ssrTransformElement: NodeTransform = (node, context) => {
159160

160161
for (let i = 0; i < node.props.length; i++) {
161162
const prop = node.props[i]
163+
// ignore true-value/false-value on input
164+
if (node.tag === 'input' && isTrueFalseValue(prop)) {
165+
continue
166+
}
162167
// special cases with children override
163168
if (prop.type === NodeTypes.DIRECTIVE) {
164169
if (prop.name === 'html' && prop.exp) {
@@ -306,6 +311,19 @@ export const ssrTransformElement: NodeTransform = (node, context) => {
306311
}
307312
}
308313

314+
function isTrueFalseValue(prop: DirectiveNode | AttributeNode) {
315+
if (prop.type === NodeTypes.DIRECTIVE) {
316+
return (
317+
prop.name === 'bind' &&
318+
prop.arg &&
319+
isStaticExp(prop.arg) &&
320+
(prop.arg.content === 'true-value' || prop.arg.content === 'false-value')
321+
)
322+
} else {
323+
return prop.name === 'true-value' || prop.name === 'false-value'
324+
}
325+
}
326+
309327
function isTextareaWithValue(
310328
node: PlainElementNode,
311329
prop: DirectiveNode

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

+28-11
Original file line numberDiff line numberDiff line change
@@ -71,19 +71,36 @@ export const ssrTransformModel: DirectiveTransform = (dir, node, context) => {
7171
]
7272
break
7373
case 'checkbox':
74-
res.props = [
75-
createObjectProperty(
76-
`checked`,
77-
createConditionalExpression(
78-
createCallExpression(`Array.isArray`, [model]),
79-
createCallExpression(context.helper(SSR_LOOSE_CONTAIN), [
74+
const trueValueBinding = findProp(node, 'true-value')
75+
if (trueValueBinding) {
76+
const trueValue =
77+
trueValueBinding.type === NodeTypes.ATTRIBUTE
78+
? JSON.stringify(trueValueBinding.value!.content)
79+
: trueValueBinding.exp!
80+
res.props = [
81+
createObjectProperty(
82+
`checked`,
83+
createCallExpression(context.helper(SSR_LOOSE_EQUAL), [
8084
model,
81-
value
82-
]),
83-
model
85+
trueValue
86+
])
8487
)
85-
)
86-
]
88+
]
89+
} else {
90+
res.props = [
91+
createObjectProperty(
92+
`checked`,
93+
createConditionalExpression(
94+
createCallExpression(`Array.isArray`, [model]),
95+
createCallExpression(context.helper(SSR_LOOSE_CONTAIN), [
96+
model,
97+
value
98+
]),
99+
model
100+
)
101+
)
102+
]
103+
}
87104
break
88105
case 'file':
89106
context.onError(

0 commit comments

Comments
 (0)