App.vue 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. <script setup lang="ts">
  2. import Header from './Header.vue'
  3. import { Repl, ReplStore } from '@vue/repl'
  4. import { ref, watchEffect } from 'vue'
  5. const setVH = () => {
  6. document.documentElement.style.setProperty('--vh', window.innerHeight + `px`)
  7. }
  8. window.addEventListener('resize', setVH)
  9. setVH()
  10. const useDevMode = ref(false)
  11. const useSSRMode = ref(false)
  12. let hash = location.hash.slice(1)
  13. if (hash.startsWith('__DEV__')) {
  14. hash = hash.slice(7)
  15. useDevMode.value = true
  16. }
  17. if (hash.startsWith('__SSR__')) {
  18. hash = hash.slice(7)
  19. useSSRMode.value = true
  20. }
  21. const store = new ReplStore({
  22. serializedState: hash,
  23. defaultVueRuntimeURL: import.meta.env.PROD
  24. ? `${location.origin}/vue.runtime.esm-browser.js`
  25. : `${location.origin}/src/vue-dev-proxy`,
  26. defaultVueServerRendererURL: import.meta.env.PROD
  27. ? `${location.origin}/server-renderer.esm-browser.js`
  28. : `${location.origin}/src/vue-server-renderer-dev-proxy`
  29. })
  30. // enable experimental features
  31. const sfcOptions = {
  32. script: {
  33. inlineTemplate: !useDevMode.value,
  34. reactivityTransform: true
  35. }
  36. }
  37. // persist state
  38. watchEffect(() => {
  39. const newHash = store
  40. .serialize()
  41. .replace(/^#/, useSSRMode.value ? `#__SSR__` : `#`)
  42. .replace(/^#/, useDevMode.value ? `#__DEV__` : `#`)
  43. history.replaceState({}, '', newHash)
  44. })
  45. function toggleDevMode() {
  46. const dev = (useDevMode.value = !useDevMode.value)
  47. sfcOptions.script.inlineTemplate = !dev
  48. store.setFiles(store.getFiles())
  49. }
  50. function toggleSSR() {
  51. useSSRMode.value = !useSSRMode.value
  52. store.setFiles(store.getFiles())
  53. }
  54. </script>
  55. <template>
  56. <Header
  57. :store="store"
  58. :dev="useDevMode"
  59. :ssr="useSSRMode"
  60. @toggle-dev="toggleDevMode"
  61. @toggle-ssr="toggleSSR"
  62. />
  63. <Repl
  64. @keydown.ctrl.s.prevent
  65. @keydown.meta.s.prevent
  66. :ssr="useSSRMode"
  67. :store="store"
  68. :showCompileOutput="true"
  69. :autoResize="true"
  70. :sfcOptions="sfcOptions"
  71. :clearConsole="false"
  72. />
  73. </template>
  74. <style>
  75. .dark {
  76. color-scheme: dark;
  77. }
  78. body {
  79. font-size: 13px;
  80. font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen,
  81. Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
  82. margin: 0;
  83. --base: #444;
  84. --nav-height: 50px;
  85. }
  86. .vue-repl {
  87. height: calc(var(--vh) - var(--nav-height));
  88. }
  89. button {
  90. border: none;
  91. outline: none;
  92. cursor: pointer;
  93. margin: 0;
  94. background-color: transparent;
  95. }
  96. </style>