fix(compiler-ssr): handle v-model checkbox with true-value binding
This commit is contained in:
parent
48f00c0f1b
commit
fe5428db12
@ -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\\")
|
||||
@ -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>', () => {
|
||||
|
@ -25,7 +25,8 @@ import {
|
||||
isBindKey,
|
||||
createSequenceExpression,
|
||||
InterpolationNode,
|
||||
isStaticExp
|
||||
isStaticExp,
|
||||
AttributeNode
|
||||
} from '@vue/compiler-dom'
|
||||
import {
|
||||
escapeHtml,
|
||||
@ -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) {
|
||||
@ -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
|
||||
|
@ -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(
|
||||
|
Loading…
Reference in New Issue
Block a user