expect((container.firstChild as any)._trueValue).toBe(true)
})
- test.todo('force hydrate checkbox with indeterminate', async () => {
+ test('force hydrate checkbox with indeterminate', async () => {
const { container } = await mountWithHydration(
'<input type="checkbox" indeterminate/>',
`<input type="checkbox" :indeterminate="true"/>`,
expect((container.firstChild! as any).indeterminate).toBe(true)
})
- test.todo(
- 'force hydrate select option with non-string value bindings',
- () => {},
- )
+ test('force hydrate select option with non-string value bindings', async () => {
+ const { container } = await mountWithHydration(
+ '<select><option value="true">ok</option></select>',
+ `<select><option :value="true">ok</option></select>`,
+ )
+ expect((container.firstChild!.firstChild as any)._value).toBe(true)
+ })
+
+ test('force hydrate v-bind with .prop modifiers', async () => {
+ const { container } = await mountWithHydration(
+ '<div .foo="true"/>',
+ `<div v-bind="data"/>`,
+ ref({ '.foo': true }),
+ )
+ expect((container.firstChild! as any).foo).toBe(true)
+ })
+ // vapor custom element not implemented yet
test.todo('force hydrate custom element with dynamic props', () => {})
})
}
}
-export function setDOMProp(el: any, key: string, value: any): void {
+export function setDOMProp(
+ el: any,
+ key: string,
+ value: any,
+ forceHydrate: boolean = false,
+): void {
if (!isApplyingFallthroughProps && el.$root && hasFallthroughKey(key)) {
return
}
(__DEV__ || __FEATURE_PROD_HYDRATION_MISMATCH_DETAILS__) &&
isHydrating &&
!attributeHasMismatch(el, key, value) &&
- !shouldForcePatch(el, key)
+ !shouldForceHydrate(el, key) &&
+ !forceHydrate
) {
return
}
patchStyle(el, el[cacheKey], (el[cacheKey] = normalizedValue))
}
-export function setValue(el: TargetElement, value: any): void {
+export function setValue(
+ el: TargetElement,
+ value: any,
+ forceHydrate: boolean = false,
+): void {
if (!isApplyingFallthroughProps && el.$root && hasFallthroughKey('value')) {
return
}
if (
(__DEV__ || __FEATURE_PROD_HYDRATION_MISMATCH_DETAILS__) &&
isHydrating &&
- !attributeHasMismatch(el, 'value', getClientText(el, value))
+ !attributeHasMismatch(el, 'value', getClientText(el, value)) &&
+ !shouldForceHydrate(el, 'value') &&
+ !forceHydrate
) {
return
}
): void {
// TODO
const isSVG = false
+ let forceHydrate = false
if (key === 'class') {
setClass(el, value)
} else if (key === 'style') {
} else if (isOn(key)) {
on(el, key[2].toLowerCase() + key.slice(3), value, { effect: true })
} else if (
- key[0] === '.'
+ // force hydrate v-bind with .prop modifiers
+ (forceHydrate = key[0] === '.')
? ((key = key.slice(1)), true)
: key[0] === '^'
? ((key = key.slice(1)), false)
} else if (key === 'textContent') {
setElementText(el, value)
} else if (key === 'value' && canSetValueDirectly(el.tagName)) {
- setValue(el, value)
+ setValue(el, value, forceHydrate)
} else {
- setDOMProp(el, key, value)
+ setDOMProp(el, key, value, forceHydrate)
}
} else {
- // TODO special case for <input v-model type="checkbox">
setAttr(el, key, value)
}
return value
return value
}
-function shouldForcePatch(el: Element, key: string): boolean {
+function shouldForceHydrate(el: Element, key: string): boolean {
const { tagName } = el
- const forcePatch = tagName === 'INPUT' || tagName === 'OPTION'
- return forcePatch && (key.endsWith('value') || key === 'indeterminate')
+ return (
+ ((tagName === 'INPUT' || tagName === 'OPTION') &&
+ (key.endsWith('value') || key === 'indeterminate')) ||
+ // force hydrate custom element dynamic props
+ tagName.includes('-')
+ )
}