Skip to content

Commit

Permalink
fix(compiler-ssr): handle v-model checkbox with true-value binding
Browse files Browse the repository at this point in the history
  • Loading branch information
yyx990803 committed Dec 1, 2020
1 parent 48f00c0 commit fe5428d
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 13 deletions.
34 changes: 33 additions & 1 deletion packages/compiler-ssr/__tests__/ssrVModel.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ describe('ssr: v-model', () => {
`)
})

test('<input type="checkbox"', () => {
test('<input type="checkbox">', () => {
expect(compileWithWrapper(`<input type="checkbox" v-model="bar">`).code)
.toMatchInlineSnapshot(`
"const { ssrLooseContain: _ssrLooseContain, ssrRenderAttrs: _ssrRenderAttrs } = require(\\"@vue/server-renderer\\")
Expand Down Expand Up @@ -81,6 +81,38 @@ describe('ssr: v-model', () => {
}></div>\`)
}"
`)

expect(
compileWithWrapper(
`<input type="checkbox" :true-value="foo" :false-value="bar" v-model="baz">`
).code
).toMatchInlineSnapshot(`
"const { ssrLooseEqual: _ssrLooseEqual, ssrRenderAttrs: _ssrRenderAttrs } = require(\\"@vue/server-renderer\\")
return function ssrRender(_ctx, _push, _parent, _attrs) {
_push(\`<div\${
_ssrRenderAttrs(_attrs)
}><input type=\\"checkbox\\"\${
(_ssrLooseEqual(_ctx.baz, _ctx.foo)) ? \\" checked\\" : \\"\\"
}></div>\`)
}"
`)

expect(
compileWithWrapper(
`<input type="checkbox" true-value="foo" false-value="bar" v-model="baz">`
).code
).toMatchInlineSnapshot(`
"const { ssrLooseEqual: _ssrLooseEqual, ssrRenderAttrs: _ssrRenderAttrs } = require(\\"@vue/server-renderer\\")
return function ssrRender(_ctx, _push, _parent, _attrs) {
_push(\`<div\${
_ssrRenderAttrs(_attrs)
}><input type=\\"checkbox\\"\${
(_ssrLooseEqual(_ctx.baz, \\"foo\\")) ? \\" checked\\" : \\"\\"
}></div>\`)
}"
`)
})

test('<textarea>', () => {
Expand Down
20 changes: 19 additions & 1 deletion packages/compiler-ssr/src/transforms/ssrTransformElement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ import {
isBindKey,
createSequenceExpression,
InterpolationNode,
isStaticExp
isStaticExp,
AttributeNode
} from '@vue/compiler-dom'
import {
escapeHtml,
Expand Down Expand Up @@ -159,6 +160,10 @@ export const ssrTransformElement: NodeTransform = (node, context) => {

for (let i = 0; i < node.props.length; i++) {
const prop = node.props[i]
// ignore true-value/false-value on input
if (node.tag === 'input' && isTrueFalseValue(prop)) {
continue
}
// special cases with children override
if (prop.type === NodeTypes.DIRECTIVE) {
if (prop.name === 'html' && prop.exp) {
Expand Down Expand Up @@ -306,6 +311,19 @@ export const ssrTransformElement: NodeTransform = (node, context) => {
}
}

function isTrueFalseValue(prop: DirectiveNode | AttributeNode) {
if (prop.type === NodeTypes.DIRECTIVE) {
return (
prop.name === 'bind' &&
prop.arg &&
isStaticExp(prop.arg) &&
(prop.arg.content === 'true-value' || prop.arg.content === 'false-value')
)
} else {
return prop.name === 'true-value' || prop.name === 'false-value'
}
}

function isTextareaWithValue(
node: PlainElementNode,
prop: DirectiveNode
Expand Down
39 changes: 28 additions & 11 deletions packages/compiler-ssr/src/transforms/ssrVModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,19 +71,36 @@ export const ssrTransformModel: DirectiveTransform = (dir, node, context) => {
]
break
case 'checkbox':
res.props = [
createObjectProperty(
`checked`,
createConditionalExpression(
createCallExpression(`Array.isArray`, [model]),
createCallExpression(context.helper(SSR_LOOSE_CONTAIN), [
const trueValueBinding = findProp(node, 'true-value')
if (trueValueBinding) {
const trueValue =
trueValueBinding.type === NodeTypes.ATTRIBUTE
? JSON.stringify(trueValueBinding.value!.content)
: trueValueBinding.exp!
res.props = [
createObjectProperty(
`checked`,
createCallExpression(context.helper(SSR_LOOSE_EQUAL), [
model,
value
]),
model
trueValue
])
)
)
]
]
} else {
res.props = [
createObjectProperty(
`checked`,
createConditionalExpression(
createCallExpression(`Array.isArray`, [model]),
createCallExpression(context.helper(SSR_LOOSE_CONTAIN), [
model,
value
]),
model
)
)
]
}
break
case 'file':
context.onError(
Expand Down

0 comments on commit fe5428d

Please sign in to comment.