Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(QImg): prevent SSR hydration error in suspense; restore placeholder image on null addImage or onError #14815, #14858 #14869

Merged
merged 3 commits into from
Nov 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
18 changes: 18 additions & 0 deletions ui/dev/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,24 @@
<div>
<router-view />

<!--
<router-view v-slot="{ Component, route }">
<template v-if="Component">
<transition name="fade" mode="out-in">
<keep-alive>
<suspense :timeout="100">
<component :is="Component" :key="route.path" />

<template #fallback>
<q-inner-loading showing size="10vmin" />
</template>
</suspense>
</keep-alive>
</transition>
</template>
</router-view>
-->

<q-btn to="/" round icon="home" dense size="xs" class="fixed dev-home-btn z-max" color="accent" aria-label="Go Home" />

<q-card
Expand Down
8 changes: 5 additions & 3 deletions ui/dev/src/boot/ssr-client.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ export default ({ router }) => {
console.log('[Quasar] On route change we deliberately load page from server -- in order to test hydration errors')

let reload = false
router.beforeEach((to, _, next) => {
router.beforeEach((to) => {
if (reload) {
window.location.href = to.fullPath
setTimeout(() => {
window.location.href = to.fullPath
}, 0)
return false
}
reload = true
next()
return true
})
}
5 changes: 4 additions & 1 deletion ui/dev/src/pages/components/img.vue
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@

<q-img
:src="bogusSrc"
placeholder-src="https://picsum.photos/500/300/?blur"
spinner-color="white"
ratio="1"
style="min-height: 100px; max-width: 225px"
Expand Down Expand Up @@ -204,7 +205,9 @@ export default {
onClick () {
console.log('@click')
}
}
} // ,

// async setup () {}
}
</script>

Expand Down
25 changes: 15 additions & 10 deletions ui/src/components/img/QImg.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import useRatio, { useRatioProps } from '../../composables/private/use-ratio.js'

import { createComponent } from '../../utils/private/create.js'
import { hSlot } from '../../utils/private/render.js'
import { isRuntimeSsrPreHydration } from '../../plugins/Platform.js'

const defaultRatio = 16 / 9

Expand Down Expand Up @@ -74,7 +73,7 @@ export default createComponent({

const images = [
ref(null),
ref(props.placeholderSrc !== void 0 ? { src: props.placeholderSrc } : null)
ref(getPlaceholderSrc())
]

const position = ref(0)
Expand Down Expand Up @@ -114,18 +113,24 @@ export default createComponent({
: null
}

function getPlaceholderSrc () {
return props.placeholderSrc !== void 0
? { src: props.placeholderSrc }
: null
}

function addImage (imgProps) {
clearTimeout(loadTimer)
hasError.value = false

if (imgProps === null) {
isLoading.value = false
images[ 0 ].value = null
images[ 1 ].value = null
return
images[ position.value ^ 1 ].value = getPlaceholderSrc()
}
else {
isLoading.value = true
}

isLoading.value = true
images[ position.value ].value = imgProps
}

Expand Down Expand Up @@ -160,7 +165,7 @@ export default createComponent({
// if component has been already destroyed
if (loadTimer === null) { return }

position.value = position.value === 1 ? 0 : 1
position.value = position.value ^ 1
images[ position.value ].value = null
isLoading.value = false
hasError.value = false
Expand All @@ -171,8 +176,8 @@ export default createComponent({
clearTimeout(loadTimer)
isLoading.value = false
hasError.value = true
images[ 0 ].value = null
images[ 1 ].value = null
images[ position.value ].value = null
images[ position.value ^ 1 ].value = getPlaceholderSrc()
emit('error', err)
}

Expand Down Expand Up @@ -242,7 +247,7 @@ export default createComponent({
}

if (__QUASAR_SSR_SERVER__ !== true) {
if (__QUASAR_SSR_CLIENT__ && isRuntimeSsrPreHydration.value === true) {
if (__QUASAR_SSR_CLIENT__) {
onMounted(() => {
addImage(getCurrentSrc())
})
Expand Down