hydration-strat-visible.html 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. <script src="../../dist/vue.global.js"></script>
  2. <div style="height: 1000px">scroll to the bottom to hydrate</div>
  3. <div id="app"><button>0</button></div>
  4. <style>
  5. body {
  6. margin: 0;
  7. }
  8. </style>
  9. <script>
  10. const rootMargin = location.search.match(/rootMargin=(\d+)/)?.[1] ?? 0
  11. const isFragment = location.search.includes('?fragment')
  12. const isVIf = location.search.includes('?v-if')
  13. if (isFragment) {
  14. document.getElementById('app').innerHTML =
  15. `<!--[--><!--[--><span>one</span><!--]--><button>0</button><span>two</span><!--]-->`
  16. } else if (isVIf) {
  17. document.getElementById('app').innerHTML = `<!---->`
  18. }
  19. window.isHydrated = false
  20. const {
  21. createSSRApp,
  22. defineAsyncComponent,
  23. h,
  24. ref,
  25. onMounted,
  26. hydrateOnVisible,
  27. createCommentVNode,
  28. } = Vue
  29. const Comp = {
  30. setup() {
  31. const count = ref(0)
  32. onMounted(() => {
  33. console.log('hydrated')
  34. window.isHydrated = true
  35. })
  36. return () => {
  37. const button = h(
  38. 'button',
  39. { onClick: () => count.value++ },
  40. count.value,
  41. )
  42. if (isVIf) {
  43. return createCommentVNode('v-if', true)
  44. } else if (isFragment) {
  45. return [[h('span', 'one')], button, h('span', 'two')]
  46. } else {
  47. return button
  48. }
  49. }
  50. },
  51. }
  52. const AsyncComp = defineAsyncComponent({
  53. loader: () => Promise.resolve(Comp),
  54. hydrate: hydrateOnVisible({ rootMargin: rootMargin + 'px' }),
  55. })
  56. createSSRApp({
  57. setup() {
  58. onMounted(() => {
  59. window.isRootMounted = true
  60. })
  61. return () => h(AsyncComp)
  62. },
  63. }).mount('#app')
  64. </script>