fix(ssr): support client-compiled v-model with dynamic type during ssr (#5787)

fix #5786
This commit is contained in:
Roan Kattouw
2022-05-17 02:52:44 -07:00
committed by GitHub
parent 847d7f782b
commit c03459b9b6
2 changed files with 131 additions and 20 deletions

View File

@@ -269,6 +269,24 @@ export const vModelDynamic: ObjectDirective<
}
}
function resolveDynamicModel(tagName: string, type: string | undefined) {
switch (tagName) {
case 'SELECT':
return vModelSelect
case 'TEXTAREA':
return vModelText
default:
switch (type) {
case 'checkbox':
return vModelCheckbox
case 'radio':
return vModelRadio
default:
return vModelText
}
}
}
function callModelHook(
el: HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement,
binding: DirectiveBinding,
@@ -276,26 +294,10 @@ function callModelHook(
prevVNode: VNode | null,
hook: keyof ObjectDirective
) {
let modelToUse: ObjectDirective
switch (el.tagName) {
case 'SELECT':
modelToUse = vModelSelect
break
case 'TEXTAREA':
modelToUse = vModelText
break
default:
switch (vnode.props && vnode.props.type) {
case 'checkbox':
modelToUse = vModelCheckbox
break
case 'radio':
modelToUse = vModelRadio
break
default:
modelToUse = vModelText
}
}
const modelToUse = resolveDynamicModel(
el.tagName,
vnode.props && vnode.props.type
)
const fn = modelToUse[hook] as DirectiveHook
fn && fn(el, binding, vnode, prevVNode)
}
@@ -324,4 +326,18 @@ export function initVModelForSSR() {
return { checked: true }
}
}
vModelDynamic.getSSRProps = (binding, vnode) => {
if (typeof vnode.type !== 'string') {
return
}
const modelToUse = resolveDynamicModel(
// resolveDynamicModel expects an uppercase tag name, but vnode.type is lowercase
vnode.type.toUpperCase(),
vnode.props && vnode.props.type
)
if (modelToUse.getSSRProps) {
return modelToUse.getSSRProps(binding, vnode)
}
}
}