├── .gitignore ├── .prettierrc.js ├── .vscode ├── extensions.json └── settings.json ├── README.md ├── cypress.config.ts ├── cypress ├── e2e │ └── basic.spec.ts └── tsconfig.json ├── index.html ├── locales ├── en.yml └── zh-CN.yml ├── package.json ├── pnpm-lock.yaml ├── public └── logo.png ├── src ├── App.vue ├── auto-imports.d.ts ├── components.d.ts ├── components │ ├── TheCounter.vue │ ├── TheFooter.vue │ └── TheInput.vue ├── composables │ └── dark.ts ├── layouts │ ├── 404.vue │ ├── default.vue │ └── home.vue ├── main.ts ├── modules │ ├── i18n.ts │ ├── nprogress.ts │ └── pinia.ts ├── pages │ ├── [...all].vue │ ├── about.md │ ├── hi │ │ └── [name].vue │ └── index.vue ├── shims.d.ts ├── stores │ └── user.ts ├── styles │ ├── main.css │ └── markdown.css └── types.ts ├── test ├── __snapshots__ │ └── component.test.ts.snap └── component.test.ts ├── tsconfig.json ├── uno.config.ts └── vite.config.ts /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .vite-ssg-dist 3 | .vite-ssg-temp 4 | *.local 5 | dist 6 | dist-ssr 7 | node_modules 8 | .idea/ 9 | *.log 10 | cypress/downloads 11 | -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | printWidth: 100, 3 | tabWidth: 2, 4 | semi: true, 5 | singleQuote: true, 6 | trailingComma: 'all', 7 | arrowParens: 'always', 8 | }; 9 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "dbaeumer.vscode-eslint", 4 | "stylelint.vscode-stylelint", 5 | "esbenp.prettier-vscode" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "eslint.validate": ["javascript", "javascriptreact", "typescript", "typescriptreact", "vue"], 3 | "stylelint.validate": ["css","scss","less","acss"], 4 | "editor.codeActionsOnSave": { 5 | "source.fixAll.eslint": true, 6 | "source.fixAll.stylelint": true 7 | }, 8 | "editor.defaultFormatter": "esbenp.prettier-vscode", 9 | "[javascript]": { 10 | "editor.defaultFormatter": "esbenp.prettier-vscode" 11 | }, 12 | "[javascriptreact]": { 13 | "editor.defaultFormatter": "esbenp.prettier-vscode" 14 | }, 15 | "[typescript]": { 16 | "editor.defaultFormatter": "esbenp.prettier-vscode" 17 | }, 18 | "[typescriptreact]": { 19 | "editor.defaultFormatter": "esbenp.prettier-vscode" 20 | }, 21 | "[vue]": { 22 | "editor.defaultFormatter": "esbenp.prettier-vscode" 23 | }, 24 | "[css]": { 25 | "editor.defaultFormatter": "esbenp.prettier-vscode" 26 | }, 27 | "[less]": { 28 | "editor.defaultFormatter": "esbenp.prettier-vscode" 29 | }, 30 | "[scss]": { 31 | "editor.defaultFormatter": "esbenp.prettier-vscode" 32 | }, 33 | "[html]": { 34 | "editor.defaultFormatter": "esbenp.prettier-vscode" 35 | }, 36 | "[json]": { 37 | "editor.defaultFormatter": "esbenp.prettier-vscode" 38 | }, 39 | "[jsonc]": { 40 | "editor.defaultFormatter": "esbenp.prettier-vscode" 41 | }, 42 | "editor.formatOnSave": true 43 | } 44 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # es6-vue-template 2 | 3 | > 印客学院 ES6 Vue 项目模板 4 | 5 | ## ⛰️ 能力支持 6 | 7 | - [`Vue Router`](https://github.com/vuejs/router) 8 | - [`vite-plugin-pages`](https://github.com/hannoeru/vite-plugin-pages) - 以文件系统为基础的路由 9 | - [`vite-plugin-vue-layouts`](https://github.com/JohnCampionJr/vite-plugin-vue-layouts) - 页面布局系统 10 | - [`Pinia`](https://pinia.vuejs.org) - 直接的, 类型安全的, 使用 Composition API 的轻便灵活的 Vue 状态管理 11 | - [`vite-plugin-vue-markdown`](https://github.com/antfu/vite-plugin-vue-markdown) - Markdown 作为组件,也可以让组件在 Markdown 中使用 12 | - [`markdown-it-prism`](https://github.com/jGleitz/markdown-it-prism) - [Prism](https://prismjs.com/) 的语法高亮 13 | - [`prism-theme-vars`](https://github.com/antfu/prism-theme-vars) - 利用 CSS 变量自定义 Prism.js 的主题 14 | - [`Vue I18n`](https://github.com/intlify/vue-i18n-next) - 国际化 15 | - [`VueUse`](https://github.com/antfu/vueuse) - 实用的 Composition API 工具合集 16 | - [`@vueuse/head`](https://github.com/vueuse/head) - 响应式地操作文档头信息 17 | - [`vite-plugin-vue-devtools`](https://github.com/webfansplz/vite-plugin-vue-devtools) - 旨在增强 Vue 开发者体验的 Vite 插件 18 | - 使用 Composition API 地 [` 16 | 17 | 18 |
19 | 20 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /locales/en.yml: -------------------------------------------------------------------------------- 1 | button: 2 | about: About 3 | back: Back 4 | go: GO 5 | home: Home 6 | toggle_dark: Toggle dark mode 7 | toggle_langs: Change languages 8 | intro: 9 | desc: encode ES6 Vue template 10 | dynamic-route: Demo of dynamic route 11 | hi: Hi, {name}! 12 | aka: Also known as 13 | whats-your-name: What's your name? 14 | not-found: Not found 15 | -------------------------------------------------------------------------------- /locales/zh-CN.yml: -------------------------------------------------------------------------------- 1 | button: 2 | about: 关于 3 | back: 返回 4 | go: 确定 5 | home: 首页 6 | toggle_dark: 切换深色模式 7 | toggle_langs: 切换语言 8 | intro: 9 | desc: 印客学院 ES6 Vue 项目模板 10 | dynamic-route: 动态路由演示 11 | hi: 你好,{name} 12 | aka: 也叫 13 | whats-your-name: 输入你的名字 14 | not-found: 未找到页面 15 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "module", 3 | "name": "es6-vue-template", 4 | "private": "true", 5 | "description": "印客学院 ES6 Vue 项目模板", 6 | "scripts": { 7 | "preinstall": "npx only-allow pnpm", 8 | "prepare": "husky install", 9 | "init": "pnpm install", 10 | "dev": "vite --port 3333 --open", 11 | "build": "vite-ssg build", 12 | "preview": "vite preview", 13 | "test": "vitest", 14 | "test:e2e": "cypress open", 15 | "test:unit": "vitest", 16 | "typecheck": "vue-tsc --noEmit", 17 | "up": "taze major -I" 18 | }, 19 | "repository": { 20 | "type": "git", 21 | "url": "git+https://github.com/encode-studio-fe/es6-vue-template.git" 22 | }, 23 | "keywords": [ 24 | "encode", 25 | "vue", 26 | "vite", 27 | "template" 28 | ], 29 | "author": "chenghuai", 30 | "license": "ISC", 31 | "bugs": { 32 | "url": "https://github.com/encode-studio-fe/es6-vue-template/issues" 33 | }, 34 | "homepage": "https://github.com/encode-studio-fe/es6-vue-template#readme", 35 | "dependencies": { 36 | "@unhead/vue": "^1.1.30", 37 | "@unocss/reset": "^0.53.5", 38 | "@vueuse/core": "^10.2.1", 39 | "@vueuse/head": "^1.1.26", 40 | "nprogress": "^0.2.0", 41 | "pinia": "^2.1.4", 42 | "vue": "^3.3.4", 43 | "vue-demi": "^0.14.5", 44 | "vue-i18n": "^9.2.2", 45 | "vue-router": "^4.2.4" 46 | }, 47 | "devDependencies": { 48 | "@iconify-json/carbon": "^1.1.18", 49 | "@intlify/unplugin-vue-i18n": "^0.12.2", 50 | "@types/markdown-it-link-attributes": "^3.0.1", 51 | "@types/nprogress": "^0.2.0", 52 | "@vitejs/plugin-vue": "^4.2.3", 53 | "@vue-macros/volar": "^0.12.1", 54 | "@vue/test-utils": "^2.4.0", 55 | "critters": "^0.0.19", 56 | "cross-env": "^7.0.3", 57 | "cypress": "^12.17.1", 58 | "cypress-vite": "^1.4.1", 59 | "eslint": "^8.44.0", 60 | "eslint-plugin-cypress": "^2.13.3", 61 | "https-localhost": "^4.7.1", 62 | "husky": "^8.0.0", 63 | "lint-staged": "^13.2.3", 64 | "markdown-it-link-attributes": "^4.0.1", 65 | "markdown-it-shiki": "^0.9.0", 66 | "pnpm": "^8.6.7", 67 | "shiki": "^0.14.3", 68 | "taze": "^0.11.2", 69 | "typescript": "^5.1.6", 70 | "unocss": "^0.53.5", 71 | "unplugin-auto-import": "^0.16.6", 72 | "unplugin-vue-components": "^0.25.1", 73 | "unplugin-vue-macros": "^2.3.6", 74 | "vite": "^4.4.3", 75 | "vite-plugin-inspect": "^0.7.32", 76 | "vite-plugin-pages": "^0.31.0", 77 | "vite-plugin-vue-component-preview": "^1.1.6", 78 | "vite-plugin-vue-devtools": "^0.5.1", 79 | "vite-plugin-vue-layouts": "^0.8.0", 80 | "vite-plugin-vue-markdown": "^0.23.5", 81 | "vite-plugin-webfont-dl": "^3.7.6", 82 | "vite-ssg": "^0.23.0", 83 | "vite-ssg-sitemap": "^0.5.1", 84 | "vitest": "^0.33.0", 85 | "vue-tsc": "^1.8.4" 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /public/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/encode-studio-fe/es6-vue-template/a271c879fb65715fc0fe4baab7f6c549e113a8fe/public/logo.png -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 24 | -------------------------------------------------------------------------------- /src/auto-imports.d.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | /* prettier-ignore */ 3 | // @ts-nocheck 4 | // noinspection JSUnusedGlobalSymbols 5 | // Generated by unplugin-auto-import 6 | export {} 7 | declare global { 8 | const EffectScope: typeof import('vue')['EffectScope'] 9 | const asyncComputed: typeof import('@vueuse/core')['asyncComputed'] 10 | const autoResetRef: typeof import('@vueuse/core')['autoResetRef'] 11 | const computed: typeof import('vue')['computed'] 12 | const computedAsync: typeof import('@vueuse/core')['computedAsync'] 13 | const computedEager: typeof import('@vueuse/core')['computedEager'] 14 | const computedInject: typeof import('@vueuse/core')['computedInject'] 15 | const computedWithControl: typeof import('@vueuse/core')['computedWithControl'] 16 | const controlledComputed: typeof import('@vueuse/core')['controlledComputed'] 17 | const controlledRef: typeof import('@vueuse/core')['controlledRef'] 18 | const createApp: typeof import('vue')['createApp'] 19 | const createEventHook: typeof import('@vueuse/core')['createEventHook'] 20 | const createGlobalState: typeof import('@vueuse/core')['createGlobalState'] 21 | const createInjectionState: typeof import('@vueuse/core')['createInjectionState'] 22 | const createReactiveFn: typeof import('@vueuse/core')['createReactiveFn'] 23 | const createReusableTemplate: typeof import('@vueuse/core')['createReusableTemplate'] 24 | const createSharedComposable: typeof import('@vueuse/core')['createSharedComposable'] 25 | const createTemplatePromise: typeof import('@vueuse/core')['createTemplatePromise'] 26 | const createUnrefFn: typeof import('@vueuse/core')['createUnrefFn'] 27 | const customRef: typeof import('vue')['customRef'] 28 | const debouncedRef: typeof import('@vueuse/core')['debouncedRef'] 29 | const debouncedWatch: typeof import('@vueuse/core')['debouncedWatch'] 30 | const defineAsyncComponent: typeof import('vue')['defineAsyncComponent'] 31 | const defineComponent: typeof import('vue')['defineComponent'] 32 | const eagerComputed: typeof import('@vueuse/core')['eagerComputed'] 33 | const effectScope: typeof import('vue')['effectScope'] 34 | const extendRef: typeof import('@vueuse/core')['extendRef'] 35 | const getCurrentInstance: typeof import('vue')['getCurrentInstance'] 36 | const getCurrentScope: typeof import('vue')['getCurrentScope'] 37 | const h: typeof import('vue')['h'] 38 | const ignorableWatch: typeof import('@vueuse/core')['ignorableWatch'] 39 | const inject: typeof import('vue')['inject'] 40 | const injectLocal: typeof import('@vueuse/core')['injectLocal'] 41 | const isDark: typeof import('./composables/dark')['isDark'] 42 | const isDefined: typeof import('@vueuse/core')['isDefined'] 43 | const isProxy: typeof import('vue')['isProxy'] 44 | const isReactive: typeof import('vue')['isReactive'] 45 | const isReadonly: typeof import('vue')['isReadonly'] 46 | const isRef: typeof import('vue')['isRef'] 47 | const makeDestructurable: typeof import('@vueuse/core')['makeDestructurable'] 48 | const markRaw: typeof import('vue')['markRaw'] 49 | const nextTick: typeof import('vue')['nextTick'] 50 | const onActivated: typeof import('vue')['onActivated'] 51 | const onBeforeMount: typeof import('vue')['onBeforeMount'] 52 | const onBeforeRouteLeave: typeof import('vue-router')['onBeforeRouteLeave'] 53 | const onBeforeRouteUpdate: typeof import('vue-router')['onBeforeRouteUpdate'] 54 | const onBeforeUnmount: typeof import('vue')['onBeforeUnmount'] 55 | const onBeforeUpdate: typeof import('vue')['onBeforeUpdate'] 56 | const onClickOutside: typeof import('@vueuse/core')['onClickOutside'] 57 | const onDeactivated: typeof import('vue')['onDeactivated'] 58 | const onErrorCaptured: typeof import('vue')['onErrorCaptured'] 59 | const onKeyStroke: typeof import('@vueuse/core')['onKeyStroke'] 60 | const onLongPress: typeof import('@vueuse/core')['onLongPress'] 61 | const onMounted: typeof import('vue')['onMounted'] 62 | const onRenderTracked: typeof import('vue')['onRenderTracked'] 63 | const onRenderTriggered: typeof import('vue')['onRenderTriggered'] 64 | const onScopeDispose: typeof import('vue')['onScopeDispose'] 65 | const onServerPrefetch: typeof import('vue')['onServerPrefetch'] 66 | const onStartTyping: typeof import('@vueuse/core')['onStartTyping'] 67 | const onUnmounted: typeof import('vue')['onUnmounted'] 68 | const onUpdated: typeof import('vue')['onUpdated'] 69 | const pausableWatch: typeof import('@vueuse/core')['pausableWatch'] 70 | const preferredDark: typeof import('./composables/dark')['preferredDark'] 71 | const provide: typeof import('vue')['provide'] 72 | const provideLocal: typeof import('@vueuse/core')['provideLocal'] 73 | const reactify: typeof import('@vueuse/core')['reactify'] 74 | const reactifyObject: typeof import('@vueuse/core')['reactifyObject'] 75 | const reactive: typeof import('vue')['reactive'] 76 | const reactiveComputed: typeof import('@vueuse/core')['reactiveComputed'] 77 | const reactiveOmit: typeof import('@vueuse/core')['reactiveOmit'] 78 | const reactivePick: typeof import('@vueuse/core')['reactivePick'] 79 | const readonly: typeof import('vue')['readonly'] 80 | const ref: typeof import('vue')['ref'] 81 | const refAutoReset: typeof import('@vueuse/core')['refAutoReset'] 82 | const refDebounced: typeof import('@vueuse/core')['refDebounced'] 83 | const refDefault: typeof import('@vueuse/core')['refDefault'] 84 | const refThrottled: typeof import('@vueuse/core')['refThrottled'] 85 | const refWithControl: typeof import('@vueuse/core')['refWithControl'] 86 | const resolveComponent: typeof import('vue')['resolveComponent'] 87 | const resolveRef: typeof import('@vueuse/core')['resolveRef'] 88 | const resolveUnref: typeof import('@vueuse/core')['resolveUnref'] 89 | const shallowReactive: typeof import('vue')['shallowReactive'] 90 | const shallowReadonly: typeof import('vue')['shallowReadonly'] 91 | const shallowRef: typeof import('vue')['shallowRef'] 92 | const syncRef: typeof import('@vueuse/core')['syncRef'] 93 | const syncRefs: typeof import('@vueuse/core')['syncRefs'] 94 | const templateRef: typeof import('@vueuse/core')['templateRef'] 95 | const throttledRef: typeof import('@vueuse/core')['throttledRef'] 96 | const throttledWatch: typeof import('@vueuse/core')['throttledWatch'] 97 | const toRaw: typeof import('vue')['toRaw'] 98 | const toReactive: typeof import('@vueuse/core')['toReactive'] 99 | const toRef: typeof import('vue')['toRef'] 100 | const toRefs: typeof import('vue')['toRefs'] 101 | const toValue: typeof import('vue')['toValue'] 102 | const toggleDark: typeof import('./composables/dark')['toggleDark'] 103 | const triggerRef: typeof import('vue')['triggerRef'] 104 | const tryOnBeforeMount: typeof import('@vueuse/core')['tryOnBeforeMount'] 105 | const tryOnBeforeUnmount: typeof import('@vueuse/core')['tryOnBeforeUnmount'] 106 | const tryOnMounted: typeof import('@vueuse/core')['tryOnMounted'] 107 | const tryOnScopeDispose: typeof import('@vueuse/core')['tryOnScopeDispose'] 108 | const tryOnUnmounted: typeof import('@vueuse/core')['tryOnUnmounted'] 109 | const unref: typeof import('vue')['unref'] 110 | const unrefElement: typeof import('@vueuse/core')['unrefElement'] 111 | const until: typeof import('@vueuse/core')['until'] 112 | const useActiveElement: typeof import('@vueuse/core')['useActiveElement'] 113 | const useAnimate: typeof import('@vueuse/core')['useAnimate'] 114 | const useArrayDifference: typeof import('@vueuse/core')['useArrayDifference'] 115 | const useArrayEvery: typeof import('@vueuse/core')['useArrayEvery'] 116 | const useArrayFilter: typeof import('@vueuse/core')['useArrayFilter'] 117 | const useArrayFind: typeof import('@vueuse/core')['useArrayFind'] 118 | const useArrayFindIndex: typeof import('@vueuse/core')['useArrayFindIndex'] 119 | const useArrayFindLast: typeof import('@vueuse/core')['useArrayFindLast'] 120 | const useArrayIncludes: typeof import('@vueuse/core')['useArrayIncludes'] 121 | const useArrayJoin: typeof import('@vueuse/core')['useArrayJoin'] 122 | const useArrayMap: typeof import('@vueuse/core')['useArrayMap'] 123 | const useArrayReduce: typeof import('@vueuse/core')['useArrayReduce'] 124 | const useArraySome: typeof import('@vueuse/core')['useArraySome'] 125 | const useArrayUnique: typeof import('@vueuse/core')['useArrayUnique'] 126 | const useAsyncQueue: typeof import('@vueuse/core')['useAsyncQueue'] 127 | const useAsyncState: typeof import('@vueuse/core')['useAsyncState'] 128 | const useAttrs: typeof import('vue')['useAttrs'] 129 | const useBase64: typeof import('@vueuse/core')['useBase64'] 130 | const useBattery: typeof import('@vueuse/core')['useBattery'] 131 | const useBluetooth: typeof import('@vueuse/core')['useBluetooth'] 132 | const useBreakpoints: typeof import('@vueuse/core')['useBreakpoints'] 133 | const useBroadcastChannel: typeof import('@vueuse/core')['useBroadcastChannel'] 134 | const useBrowserLocation: typeof import('@vueuse/core')['useBrowserLocation'] 135 | const useCached: typeof import('@vueuse/core')['useCached'] 136 | const useClipboard: typeof import('@vueuse/core')['useClipboard'] 137 | const useClipboardItems: typeof import('@vueuse/core')['useClipboardItems'] 138 | const useCloned: typeof import('@vueuse/core')['useCloned'] 139 | const useColorMode: typeof import('@vueuse/core')['useColorMode'] 140 | const useConfirmDialog: typeof import('@vueuse/core')['useConfirmDialog'] 141 | const useCounter: typeof import('@vueuse/core')['useCounter'] 142 | const useCssModule: typeof import('vue')['useCssModule'] 143 | const useCssVar: typeof import('@vueuse/core')['useCssVar'] 144 | const useCssVars: typeof import('vue')['useCssVars'] 145 | const useCurrentElement: typeof import('@vueuse/core')['useCurrentElement'] 146 | const useCycleList: typeof import('@vueuse/core')['useCycleList'] 147 | const useDark: typeof import('@vueuse/core')['useDark'] 148 | const useDateFormat: typeof import('@vueuse/core')['useDateFormat'] 149 | const useDebounce: typeof import('@vueuse/core')['useDebounce'] 150 | const useDebounceFn: typeof import('@vueuse/core')['useDebounceFn'] 151 | const useDebouncedRefHistory: typeof import('@vueuse/core')['useDebouncedRefHistory'] 152 | const useDeviceMotion: typeof import('@vueuse/core')['useDeviceMotion'] 153 | const useDeviceOrientation: typeof import('@vueuse/core')['useDeviceOrientation'] 154 | const useDevicePixelRatio: typeof import('@vueuse/core')['useDevicePixelRatio'] 155 | const useDevicesList: typeof import('@vueuse/core')['useDevicesList'] 156 | const useDisplayMedia: typeof import('@vueuse/core')['useDisplayMedia'] 157 | const useDocumentVisibility: typeof import('@vueuse/core')['useDocumentVisibility'] 158 | const useDraggable: typeof import('@vueuse/core')['useDraggable'] 159 | const useDropZone: typeof import('@vueuse/core')['useDropZone'] 160 | const useElementBounding: typeof import('@vueuse/core')['useElementBounding'] 161 | const useElementByPoint: typeof import('@vueuse/core')['useElementByPoint'] 162 | const useElementHover: typeof import('@vueuse/core')['useElementHover'] 163 | const useElementSize: typeof import('@vueuse/core')['useElementSize'] 164 | const useElementVisibility: typeof import('@vueuse/core')['useElementVisibility'] 165 | const useEventBus: typeof import('@vueuse/core')['useEventBus'] 166 | const useEventListener: typeof import('@vueuse/core')['useEventListener'] 167 | const useEventSource: typeof import('@vueuse/core')['useEventSource'] 168 | const useEyeDropper: typeof import('@vueuse/core')['useEyeDropper'] 169 | const useFavicon: typeof import('@vueuse/core')['useFavicon'] 170 | const useFetch: typeof import('@vueuse/core')['useFetch'] 171 | const useFileDialog: typeof import('@vueuse/core')['useFileDialog'] 172 | const useFileSystemAccess: typeof import('@vueuse/core')['useFileSystemAccess'] 173 | const useFocus: typeof import('@vueuse/core')['useFocus'] 174 | const useFocusWithin: typeof import('@vueuse/core')['useFocusWithin'] 175 | const useFps: typeof import('@vueuse/core')['useFps'] 176 | const useFullscreen: typeof import('@vueuse/core')['useFullscreen'] 177 | const useGamepad: typeof import('@vueuse/core')['useGamepad'] 178 | const useGeolocation: typeof import('@vueuse/core')['useGeolocation'] 179 | const useHead: typeof import('@vueuse/head')['useHead'] 180 | const useI18n: typeof import('vue-i18n')['useI18n'] 181 | const useIdle: typeof import('@vueuse/core')['useIdle'] 182 | const useImage: typeof import('@vueuse/core')['useImage'] 183 | const useInfiniteScroll: typeof import('@vueuse/core')['useInfiniteScroll'] 184 | const useIntersectionObserver: typeof import('@vueuse/core')['useIntersectionObserver'] 185 | const useInterval: typeof import('@vueuse/core')['useInterval'] 186 | const useIntervalFn: typeof import('@vueuse/core')['useIntervalFn'] 187 | const useKeyModifier: typeof import('@vueuse/core')['useKeyModifier'] 188 | const useLastChanged: typeof import('@vueuse/core')['useLastChanged'] 189 | const useLink: typeof import('vue-router')['useLink'] 190 | const useLocalStorage: typeof import('@vueuse/core')['useLocalStorage'] 191 | const useMagicKeys: typeof import('@vueuse/core')['useMagicKeys'] 192 | const useManualRefHistory: typeof import('@vueuse/core')['useManualRefHistory'] 193 | const useMediaControls: typeof import('@vueuse/core')['useMediaControls'] 194 | const useMediaQuery: typeof import('@vueuse/core')['useMediaQuery'] 195 | const useMemoize: typeof import('@vueuse/core')['useMemoize'] 196 | const useMemory: typeof import('@vueuse/core')['useMemory'] 197 | const useMounted: typeof import('@vueuse/core')['useMounted'] 198 | const useMouse: typeof import('@vueuse/core')['useMouse'] 199 | const useMouseInElement: typeof import('@vueuse/core')['useMouseInElement'] 200 | const useMousePressed: typeof import('@vueuse/core')['useMousePressed'] 201 | const useMutationObserver: typeof import('@vueuse/core')['useMutationObserver'] 202 | const useNavigatorLanguage: typeof import('@vueuse/core')['useNavigatorLanguage'] 203 | const useNetwork: typeof import('@vueuse/core')['useNetwork'] 204 | const useNow: typeof import('@vueuse/core')['useNow'] 205 | const useObjectUrl: typeof import('@vueuse/core')['useObjectUrl'] 206 | const useOffsetPagination: typeof import('@vueuse/core')['useOffsetPagination'] 207 | const useOnline: typeof import('@vueuse/core')['useOnline'] 208 | const usePageLeave: typeof import('@vueuse/core')['usePageLeave'] 209 | const useParallax: typeof import('@vueuse/core')['useParallax'] 210 | const useParentElement: typeof import('@vueuse/core')['useParentElement'] 211 | const usePerformanceObserver: typeof import('@vueuse/core')['usePerformanceObserver'] 212 | const usePermission: typeof import('@vueuse/core')['usePermission'] 213 | const usePointer: typeof import('@vueuse/core')['usePointer'] 214 | const usePointerLock: typeof import('@vueuse/core')['usePointerLock'] 215 | const usePointerSwipe: typeof import('@vueuse/core')['usePointerSwipe'] 216 | const usePreferredColorScheme: typeof import('@vueuse/core')['usePreferredColorScheme'] 217 | const usePreferredContrast: typeof import('@vueuse/core')['usePreferredContrast'] 218 | const usePreferredDark: typeof import('@vueuse/core')['usePreferredDark'] 219 | const usePreferredLanguages: typeof import('@vueuse/core')['usePreferredLanguages'] 220 | const usePreferredReducedMotion: typeof import('@vueuse/core')['usePreferredReducedMotion'] 221 | const usePrevious: typeof import('@vueuse/core')['usePrevious'] 222 | const useRafFn: typeof import('@vueuse/core')['useRafFn'] 223 | const useRefHistory: typeof import('@vueuse/core')['useRefHistory'] 224 | const useResizeObserver: typeof import('@vueuse/core')['useResizeObserver'] 225 | const useRoute: typeof import('vue-router')['useRoute'] 226 | const useRouter: typeof import('vue-router')['useRouter'] 227 | const useScreenOrientation: typeof import('@vueuse/core')['useScreenOrientation'] 228 | const useScreenSafeArea: typeof import('@vueuse/core')['useScreenSafeArea'] 229 | const useScriptTag: typeof import('@vueuse/core')['useScriptTag'] 230 | const useScroll: typeof import('@vueuse/core')['useScroll'] 231 | const useScrollLock: typeof import('@vueuse/core')['useScrollLock'] 232 | const useSeoMeta: typeof import('@vueuse/head')['useSeoMeta'] 233 | const useSessionStorage: typeof import('@vueuse/core')['useSessionStorage'] 234 | const useShare: typeof import('@vueuse/core')['useShare'] 235 | const useSlots: typeof import('vue')['useSlots'] 236 | const useSorted: typeof import('@vueuse/core')['useSorted'] 237 | const useSpeechRecognition: typeof import('@vueuse/core')['useSpeechRecognition'] 238 | const useSpeechSynthesis: typeof import('@vueuse/core')['useSpeechSynthesis'] 239 | const useStepper: typeof import('@vueuse/core')['useStepper'] 240 | const useStorage: typeof import('@vueuse/core')['useStorage'] 241 | const useStorageAsync: typeof import('@vueuse/core')['useStorageAsync'] 242 | const useStyleTag: typeof import('@vueuse/core')['useStyleTag'] 243 | const useSupported: typeof import('@vueuse/core')['useSupported'] 244 | const useSwipe: typeof import('@vueuse/core')['useSwipe'] 245 | const useTemplateRefsList: typeof import('@vueuse/core')['useTemplateRefsList'] 246 | const useTextDirection: typeof import('@vueuse/core')['useTextDirection'] 247 | const useTextSelection: typeof import('@vueuse/core')['useTextSelection'] 248 | const useTextareaAutosize: typeof import('@vueuse/core')['useTextareaAutosize'] 249 | const useThrottle: typeof import('@vueuse/core')['useThrottle'] 250 | const useThrottleFn: typeof import('@vueuse/core')['useThrottleFn'] 251 | const useThrottledRefHistory: typeof import('@vueuse/core')['useThrottledRefHistory'] 252 | const useTimeAgo: typeof import('@vueuse/core')['useTimeAgo'] 253 | const useTimeout: typeof import('@vueuse/core')['useTimeout'] 254 | const useTimeoutFn: typeof import('@vueuse/core')['useTimeoutFn'] 255 | const useTimeoutPoll: typeof import('@vueuse/core')['useTimeoutPoll'] 256 | const useTimestamp: typeof import('@vueuse/core')['useTimestamp'] 257 | const useTitle: typeof import('@vueuse/core')['useTitle'] 258 | const useToNumber: typeof import('@vueuse/core')['useToNumber'] 259 | const useToString: typeof import('@vueuse/core')['useToString'] 260 | const useToggle: typeof import('@vueuse/core')['useToggle'] 261 | const useTransition: typeof import('@vueuse/core')['useTransition'] 262 | const useUrlSearchParams: typeof import('@vueuse/core')['useUrlSearchParams'] 263 | const useUserMedia: typeof import('@vueuse/core')['useUserMedia'] 264 | const useUserStore: typeof import('./stores/user')['useUserStore'] 265 | const useVModel: typeof import('@vueuse/core')['useVModel'] 266 | const useVModels: typeof import('@vueuse/core')['useVModels'] 267 | const useVibrate: typeof import('@vueuse/core')['useVibrate'] 268 | const useVirtualList: typeof import('@vueuse/core')['useVirtualList'] 269 | const useWakeLock: typeof import('@vueuse/core')['useWakeLock'] 270 | const useWebNotification: typeof import('@vueuse/core')['useWebNotification'] 271 | const useWebSocket: typeof import('@vueuse/core')['useWebSocket'] 272 | const useWebWorker: typeof import('@vueuse/core')['useWebWorker'] 273 | const useWebWorkerFn: typeof import('@vueuse/core')['useWebWorkerFn'] 274 | const useWindowFocus: typeof import('@vueuse/core')['useWindowFocus'] 275 | const useWindowScroll: typeof import('@vueuse/core')['useWindowScroll'] 276 | const useWindowSize: typeof import('@vueuse/core')['useWindowSize'] 277 | const watch: typeof import('vue')['watch'] 278 | const watchArray: typeof import('@vueuse/core')['watchArray'] 279 | const watchAtMost: typeof import('@vueuse/core')['watchAtMost'] 280 | const watchDebounced: typeof import('@vueuse/core')['watchDebounced'] 281 | const watchDeep: typeof import('@vueuse/core')['watchDeep'] 282 | const watchEffect: typeof import('vue')['watchEffect'] 283 | const watchIgnorable: typeof import('@vueuse/core')['watchIgnorable'] 284 | const watchImmediate: typeof import('@vueuse/core')['watchImmediate'] 285 | const watchOnce: typeof import('@vueuse/core')['watchOnce'] 286 | const watchPausable: typeof import('@vueuse/core')['watchPausable'] 287 | const watchPostEffect: typeof import('vue')['watchPostEffect'] 288 | const watchSyncEffect: typeof import('vue')['watchSyncEffect'] 289 | const watchThrottled: typeof import('@vueuse/core')['watchThrottled'] 290 | const watchTriggerable: typeof import('@vueuse/core')['watchTriggerable'] 291 | const watchWithFilter: typeof import('@vueuse/core')['watchWithFilter'] 292 | const whenever: typeof import('@vueuse/core')['whenever'] 293 | } 294 | // for type re-export 295 | declare global { 296 | // @ts-ignore 297 | export type { Component, ComponentPublicInstance, ComputedRef, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, VNode, WritableComputedRef } from 'vue' 298 | import('vue') 299 | } 300 | // for vue template auto import 301 | import { UnwrapRef } from 'vue' 302 | declare module 'vue' { 303 | interface ComponentCustomProperties { 304 | readonly EffectScope: UnwrapRef 305 | readonly asyncComputed: UnwrapRef 306 | readonly autoResetRef: UnwrapRef 307 | readonly computed: UnwrapRef 308 | readonly computedAsync: UnwrapRef 309 | readonly computedEager: UnwrapRef 310 | readonly computedInject: UnwrapRef 311 | readonly computedWithControl: UnwrapRef 312 | readonly controlledComputed: UnwrapRef 313 | readonly controlledRef: UnwrapRef 314 | readonly createApp: UnwrapRef 315 | readonly createEventHook: UnwrapRef 316 | readonly createGlobalState: UnwrapRef 317 | readonly createInjectionState: UnwrapRef 318 | readonly createReactiveFn: UnwrapRef 319 | readonly createReusableTemplate: UnwrapRef 320 | readonly createSharedComposable: UnwrapRef 321 | readonly createTemplatePromise: UnwrapRef 322 | readonly createUnrefFn: UnwrapRef 323 | readonly customRef: UnwrapRef 324 | readonly debouncedRef: UnwrapRef 325 | readonly debouncedWatch: UnwrapRef 326 | readonly defineAsyncComponent: UnwrapRef 327 | readonly defineComponent: UnwrapRef 328 | readonly eagerComputed: UnwrapRef 329 | readonly effectScope: UnwrapRef 330 | readonly extendRef: UnwrapRef 331 | readonly getCurrentInstance: UnwrapRef 332 | readonly getCurrentScope: UnwrapRef 333 | readonly h: UnwrapRef 334 | readonly ignorableWatch: UnwrapRef 335 | readonly inject: UnwrapRef 336 | readonly injectLocal: UnwrapRef 337 | readonly isDark: UnwrapRef 338 | readonly isDefined: UnwrapRef 339 | readonly isProxy: UnwrapRef 340 | readonly isReactive: UnwrapRef 341 | readonly isReadonly: UnwrapRef 342 | readonly isRef: UnwrapRef 343 | readonly makeDestructurable: UnwrapRef 344 | readonly markRaw: UnwrapRef 345 | readonly nextTick: UnwrapRef 346 | readonly onActivated: UnwrapRef 347 | readonly onBeforeMount: UnwrapRef 348 | readonly onBeforeRouteLeave: UnwrapRef 349 | readonly onBeforeRouteUpdate: UnwrapRef 350 | readonly onBeforeUnmount: UnwrapRef 351 | readonly onBeforeUpdate: UnwrapRef 352 | readonly onClickOutside: UnwrapRef 353 | readonly onDeactivated: UnwrapRef 354 | readonly onErrorCaptured: UnwrapRef 355 | readonly onKeyStroke: UnwrapRef 356 | readonly onLongPress: UnwrapRef 357 | readonly onMounted: UnwrapRef 358 | readonly onRenderTracked: UnwrapRef 359 | readonly onRenderTriggered: UnwrapRef 360 | readonly onScopeDispose: UnwrapRef 361 | readonly onServerPrefetch: UnwrapRef 362 | readonly onStartTyping: UnwrapRef 363 | readonly onUnmounted: UnwrapRef 364 | readonly onUpdated: UnwrapRef 365 | readonly pausableWatch: UnwrapRef 366 | readonly preferredDark: UnwrapRef 367 | readonly provide: UnwrapRef 368 | readonly provideLocal: UnwrapRef 369 | readonly reactify: UnwrapRef 370 | readonly reactifyObject: UnwrapRef 371 | readonly reactive: UnwrapRef 372 | readonly reactiveComputed: UnwrapRef 373 | readonly reactiveOmit: UnwrapRef 374 | readonly reactivePick: UnwrapRef 375 | readonly readonly: UnwrapRef 376 | readonly ref: UnwrapRef 377 | readonly refAutoReset: UnwrapRef 378 | readonly refDebounced: UnwrapRef 379 | readonly refDefault: UnwrapRef 380 | readonly refThrottled: UnwrapRef 381 | readonly refWithControl: UnwrapRef 382 | readonly resolveComponent: UnwrapRef 383 | readonly resolveRef: UnwrapRef 384 | readonly resolveUnref: UnwrapRef 385 | readonly shallowReactive: UnwrapRef 386 | readonly shallowReadonly: UnwrapRef 387 | readonly shallowRef: UnwrapRef 388 | readonly syncRef: UnwrapRef 389 | readonly syncRefs: UnwrapRef 390 | readonly templateRef: UnwrapRef 391 | readonly throttledRef: UnwrapRef 392 | readonly throttledWatch: UnwrapRef 393 | readonly toRaw: UnwrapRef 394 | readonly toReactive: UnwrapRef 395 | readonly toRef: UnwrapRef 396 | readonly toRefs: UnwrapRef 397 | readonly toValue: UnwrapRef 398 | readonly toggleDark: UnwrapRef 399 | readonly triggerRef: UnwrapRef 400 | readonly tryOnBeforeMount: UnwrapRef 401 | readonly tryOnBeforeUnmount: UnwrapRef 402 | readonly tryOnMounted: UnwrapRef 403 | readonly tryOnScopeDispose: UnwrapRef 404 | readonly tryOnUnmounted: UnwrapRef 405 | readonly unref: UnwrapRef 406 | readonly unrefElement: UnwrapRef 407 | readonly until: UnwrapRef 408 | readonly useActiveElement: UnwrapRef 409 | readonly useAnimate: UnwrapRef 410 | readonly useArrayDifference: UnwrapRef 411 | readonly useArrayEvery: UnwrapRef 412 | readonly useArrayFilter: UnwrapRef 413 | readonly useArrayFind: UnwrapRef 414 | readonly useArrayFindIndex: UnwrapRef 415 | readonly useArrayFindLast: UnwrapRef 416 | readonly useArrayIncludes: UnwrapRef 417 | readonly useArrayJoin: UnwrapRef 418 | readonly useArrayMap: UnwrapRef 419 | readonly useArrayReduce: UnwrapRef 420 | readonly useArraySome: UnwrapRef 421 | readonly useArrayUnique: UnwrapRef 422 | readonly useAsyncQueue: UnwrapRef 423 | readonly useAsyncState: UnwrapRef 424 | readonly useAttrs: UnwrapRef 425 | readonly useBase64: UnwrapRef 426 | readonly useBattery: UnwrapRef 427 | readonly useBluetooth: UnwrapRef 428 | readonly useBreakpoints: UnwrapRef 429 | readonly useBroadcastChannel: UnwrapRef 430 | readonly useBrowserLocation: UnwrapRef 431 | readonly useCached: UnwrapRef 432 | readonly useClipboard: UnwrapRef 433 | readonly useClipboardItems: UnwrapRef 434 | readonly useCloned: UnwrapRef 435 | readonly useColorMode: UnwrapRef 436 | readonly useConfirmDialog: UnwrapRef 437 | readonly useCounter: UnwrapRef 438 | readonly useCssModule: UnwrapRef 439 | readonly useCssVar: UnwrapRef 440 | readonly useCssVars: UnwrapRef 441 | readonly useCurrentElement: UnwrapRef 442 | readonly useCycleList: UnwrapRef 443 | readonly useDark: UnwrapRef 444 | readonly useDateFormat: UnwrapRef 445 | readonly useDebounce: UnwrapRef 446 | readonly useDebounceFn: UnwrapRef 447 | readonly useDebouncedRefHistory: UnwrapRef 448 | readonly useDeviceMotion: UnwrapRef 449 | readonly useDeviceOrientation: UnwrapRef 450 | readonly useDevicePixelRatio: UnwrapRef 451 | readonly useDevicesList: UnwrapRef 452 | readonly useDisplayMedia: UnwrapRef 453 | readonly useDocumentVisibility: UnwrapRef 454 | readonly useDraggable: UnwrapRef 455 | readonly useDropZone: UnwrapRef 456 | readonly useElementBounding: UnwrapRef 457 | readonly useElementByPoint: UnwrapRef 458 | readonly useElementHover: UnwrapRef 459 | readonly useElementSize: UnwrapRef 460 | readonly useElementVisibility: UnwrapRef 461 | readonly useEventBus: UnwrapRef 462 | readonly useEventListener: UnwrapRef 463 | readonly useEventSource: UnwrapRef 464 | readonly useEyeDropper: UnwrapRef 465 | readonly useFavicon: UnwrapRef 466 | readonly useFetch: UnwrapRef 467 | readonly useFileDialog: UnwrapRef 468 | readonly useFileSystemAccess: UnwrapRef 469 | readonly useFocus: UnwrapRef 470 | readonly useFocusWithin: UnwrapRef 471 | readonly useFps: UnwrapRef 472 | readonly useFullscreen: UnwrapRef 473 | readonly useGamepad: UnwrapRef 474 | readonly useGeolocation: UnwrapRef 475 | readonly useHead: UnwrapRef 476 | readonly useI18n: UnwrapRef 477 | readonly useIdle: UnwrapRef 478 | readonly useImage: UnwrapRef 479 | readonly useInfiniteScroll: UnwrapRef 480 | readonly useIntersectionObserver: UnwrapRef 481 | readonly useInterval: UnwrapRef 482 | readonly useIntervalFn: UnwrapRef 483 | readonly useKeyModifier: UnwrapRef 484 | readonly useLastChanged: UnwrapRef 485 | readonly useLink: UnwrapRef 486 | readonly useLocalStorage: UnwrapRef 487 | readonly useMagicKeys: UnwrapRef 488 | readonly useManualRefHistory: UnwrapRef 489 | readonly useMediaControls: UnwrapRef 490 | readonly useMediaQuery: UnwrapRef 491 | readonly useMemoize: UnwrapRef 492 | readonly useMemory: UnwrapRef 493 | readonly useMounted: UnwrapRef 494 | readonly useMouse: UnwrapRef 495 | readonly useMouseInElement: UnwrapRef 496 | readonly useMousePressed: UnwrapRef 497 | readonly useMutationObserver: UnwrapRef 498 | readonly useNavigatorLanguage: UnwrapRef 499 | readonly useNetwork: UnwrapRef 500 | readonly useNow: UnwrapRef 501 | readonly useObjectUrl: UnwrapRef 502 | readonly useOffsetPagination: UnwrapRef 503 | readonly useOnline: UnwrapRef 504 | readonly usePageLeave: UnwrapRef 505 | readonly useParallax: UnwrapRef 506 | readonly useParentElement: UnwrapRef 507 | readonly usePerformanceObserver: UnwrapRef 508 | readonly usePermission: UnwrapRef 509 | readonly usePointer: UnwrapRef 510 | readonly usePointerLock: UnwrapRef 511 | readonly usePointerSwipe: UnwrapRef 512 | readonly usePreferredColorScheme: UnwrapRef 513 | readonly usePreferredContrast: UnwrapRef 514 | readonly usePreferredDark: UnwrapRef 515 | readonly usePreferredLanguages: UnwrapRef 516 | readonly usePreferredReducedMotion: UnwrapRef 517 | readonly usePrevious: UnwrapRef 518 | readonly useRafFn: UnwrapRef 519 | readonly useRefHistory: UnwrapRef 520 | readonly useResizeObserver: UnwrapRef 521 | readonly useRoute: UnwrapRef 522 | readonly useRouter: UnwrapRef 523 | readonly useScreenOrientation: UnwrapRef 524 | readonly useScreenSafeArea: UnwrapRef 525 | readonly useScriptTag: UnwrapRef 526 | readonly useScroll: UnwrapRef 527 | readonly useScrollLock: UnwrapRef 528 | readonly useSeoMeta: UnwrapRef 529 | readonly useSessionStorage: UnwrapRef 530 | readonly useShare: UnwrapRef 531 | readonly useSlots: UnwrapRef 532 | readonly useSorted: UnwrapRef 533 | readonly useSpeechRecognition: UnwrapRef 534 | readonly useSpeechSynthesis: UnwrapRef 535 | readonly useStepper: UnwrapRef 536 | readonly useStorage: UnwrapRef 537 | readonly useStorageAsync: UnwrapRef 538 | readonly useStyleTag: UnwrapRef 539 | readonly useSupported: UnwrapRef 540 | readonly useSwipe: UnwrapRef 541 | readonly useTemplateRefsList: UnwrapRef 542 | readonly useTextDirection: UnwrapRef 543 | readonly useTextSelection: UnwrapRef 544 | readonly useTextareaAutosize: UnwrapRef 545 | readonly useThrottle: UnwrapRef 546 | readonly useThrottleFn: UnwrapRef 547 | readonly useThrottledRefHistory: UnwrapRef 548 | readonly useTimeAgo: UnwrapRef 549 | readonly useTimeout: UnwrapRef 550 | readonly useTimeoutFn: UnwrapRef 551 | readonly useTimeoutPoll: UnwrapRef 552 | readonly useTimestamp: UnwrapRef 553 | readonly useTitle: UnwrapRef 554 | readonly useToNumber: UnwrapRef 555 | readonly useToString: UnwrapRef 556 | readonly useToggle: UnwrapRef 557 | readonly useTransition: UnwrapRef 558 | readonly useUrlSearchParams: UnwrapRef 559 | readonly useUserMedia: UnwrapRef 560 | readonly useUserStore: UnwrapRef 561 | readonly useVModel: UnwrapRef 562 | readonly useVModels: UnwrapRef 563 | readonly useVibrate: UnwrapRef 564 | readonly useVirtualList: UnwrapRef 565 | readonly useWakeLock: UnwrapRef 566 | readonly useWebNotification: UnwrapRef 567 | readonly useWebSocket: UnwrapRef 568 | readonly useWebWorker: UnwrapRef 569 | readonly useWebWorkerFn: UnwrapRef 570 | readonly useWindowFocus: UnwrapRef 571 | readonly useWindowScroll: UnwrapRef 572 | readonly useWindowSize: UnwrapRef 573 | readonly watch: UnwrapRef 574 | readonly watchArray: UnwrapRef 575 | readonly watchAtMost: UnwrapRef 576 | readonly watchDebounced: UnwrapRef 577 | readonly watchDeep: UnwrapRef 578 | readonly watchEffect: UnwrapRef 579 | readonly watchIgnorable: UnwrapRef 580 | readonly watchImmediate: UnwrapRef 581 | readonly watchOnce: UnwrapRef 582 | readonly watchPausable: UnwrapRef 583 | readonly watchPostEffect: UnwrapRef 584 | readonly watchSyncEffect: UnwrapRef 585 | readonly watchThrottled: UnwrapRef 586 | readonly watchTriggerable: UnwrapRef 587 | readonly watchWithFilter: UnwrapRef 588 | readonly whenever: UnwrapRef 589 | } 590 | } 591 | declare module '@vue/runtime-core' { 592 | interface ComponentCustomProperties { 593 | readonly EffectScope: UnwrapRef 594 | readonly asyncComputed: UnwrapRef 595 | readonly autoResetRef: UnwrapRef 596 | readonly computed: UnwrapRef 597 | readonly computedAsync: UnwrapRef 598 | readonly computedEager: UnwrapRef 599 | readonly computedInject: UnwrapRef 600 | readonly computedWithControl: UnwrapRef 601 | readonly controlledComputed: UnwrapRef 602 | readonly controlledRef: UnwrapRef 603 | readonly createApp: UnwrapRef 604 | readonly createEventHook: UnwrapRef 605 | readonly createGlobalState: UnwrapRef 606 | readonly createInjectionState: UnwrapRef 607 | readonly createReactiveFn: UnwrapRef 608 | readonly createReusableTemplate: UnwrapRef 609 | readonly createSharedComposable: UnwrapRef 610 | readonly createTemplatePromise: UnwrapRef 611 | readonly createUnrefFn: UnwrapRef 612 | readonly customRef: UnwrapRef 613 | readonly debouncedRef: UnwrapRef 614 | readonly debouncedWatch: UnwrapRef 615 | readonly defineAsyncComponent: UnwrapRef 616 | readonly defineComponent: UnwrapRef 617 | readonly eagerComputed: UnwrapRef 618 | readonly effectScope: UnwrapRef 619 | readonly extendRef: UnwrapRef 620 | readonly getCurrentInstance: UnwrapRef 621 | readonly getCurrentScope: UnwrapRef 622 | readonly h: UnwrapRef 623 | readonly ignorableWatch: UnwrapRef 624 | readonly inject: UnwrapRef 625 | readonly injectLocal: UnwrapRef 626 | readonly isDark: UnwrapRef 627 | readonly isDefined: UnwrapRef 628 | readonly isProxy: UnwrapRef 629 | readonly isReactive: UnwrapRef 630 | readonly isReadonly: UnwrapRef 631 | readonly isRef: UnwrapRef 632 | readonly makeDestructurable: UnwrapRef 633 | readonly markRaw: UnwrapRef 634 | readonly nextTick: UnwrapRef 635 | readonly onActivated: UnwrapRef 636 | readonly onBeforeMount: UnwrapRef 637 | readonly onBeforeRouteLeave: UnwrapRef 638 | readonly onBeforeRouteUpdate: UnwrapRef 639 | readonly onBeforeUnmount: UnwrapRef 640 | readonly onBeforeUpdate: UnwrapRef 641 | readonly onClickOutside: UnwrapRef 642 | readonly onDeactivated: UnwrapRef 643 | readonly onErrorCaptured: UnwrapRef 644 | readonly onKeyStroke: UnwrapRef 645 | readonly onLongPress: UnwrapRef 646 | readonly onMounted: UnwrapRef 647 | readonly onRenderTracked: UnwrapRef 648 | readonly onRenderTriggered: UnwrapRef 649 | readonly onScopeDispose: UnwrapRef 650 | readonly onServerPrefetch: UnwrapRef 651 | readonly onStartTyping: UnwrapRef 652 | readonly onUnmounted: UnwrapRef 653 | readonly onUpdated: UnwrapRef 654 | readonly pausableWatch: UnwrapRef 655 | readonly preferredDark: UnwrapRef 656 | readonly provide: UnwrapRef 657 | readonly provideLocal: UnwrapRef 658 | readonly reactify: UnwrapRef 659 | readonly reactifyObject: UnwrapRef 660 | readonly reactive: UnwrapRef 661 | readonly reactiveComputed: UnwrapRef 662 | readonly reactiveOmit: UnwrapRef 663 | readonly reactivePick: UnwrapRef 664 | readonly readonly: UnwrapRef 665 | readonly ref: UnwrapRef 666 | readonly refAutoReset: UnwrapRef 667 | readonly refDebounced: UnwrapRef 668 | readonly refDefault: UnwrapRef 669 | readonly refThrottled: UnwrapRef 670 | readonly refWithControl: UnwrapRef 671 | readonly resolveComponent: UnwrapRef 672 | readonly resolveRef: UnwrapRef 673 | readonly resolveUnref: UnwrapRef 674 | readonly shallowReactive: UnwrapRef 675 | readonly shallowReadonly: UnwrapRef 676 | readonly shallowRef: UnwrapRef 677 | readonly syncRef: UnwrapRef 678 | readonly syncRefs: UnwrapRef 679 | readonly templateRef: UnwrapRef 680 | readonly throttledRef: UnwrapRef 681 | readonly throttledWatch: UnwrapRef 682 | readonly toRaw: UnwrapRef 683 | readonly toReactive: UnwrapRef 684 | readonly toRef: UnwrapRef 685 | readonly toRefs: UnwrapRef 686 | readonly toValue: UnwrapRef 687 | readonly toggleDark: UnwrapRef 688 | readonly triggerRef: UnwrapRef 689 | readonly tryOnBeforeMount: UnwrapRef 690 | readonly tryOnBeforeUnmount: UnwrapRef 691 | readonly tryOnMounted: UnwrapRef 692 | readonly tryOnScopeDispose: UnwrapRef 693 | readonly tryOnUnmounted: UnwrapRef 694 | readonly unref: UnwrapRef 695 | readonly unrefElement: UnwrapRef 696 | readonly until: UnwrapRef 697 | readonly useActiveElement: UnwrapRef 698 | readonly useAnimate: UnwrapRef 699 | readonly useArrayDifference: UnwrapRef 700 | readonly useArrayEvery: UnwrapRef 701 | readonly useArrayFilter: UnwrapRef 702 | readonly useArrayFind: UnwrapRef 703 | readonly useArrayFindIndex: UnwrapRef 704 | readonly useArrayFindLast: UnwrapRef 705 | readonly useArrayIncludes: UnwrapRef 706 | readonly useArrayJoin: UnwrapRef 707 | readonly useArrayMap: UnwrapRef 708 | readonly useArrayReduce: UnwrapRef 709 | readonly useArraySome: UnwrapRef 710 | readonly useArrayUnique: UnwrapRef 711 | readonly useAsyncQueue: UnwrapRef 712 | readonly useAsyncState: UnwrapRef 713 | readonly useAttrs: UnwrapRef 714 | readonly useBase64: UnwrapRef 715 | readonly useBattery: UnwrapRef 716 | readonly useBluetooth: UnwrapRef 717 | readonly useBreakpoints: UnwrapRef 718 | readonly useBroadcastChannel: UnwrapRef 719 | readonly useBrowserLocation: UnwrapRef 720 | readonly useCached: UnwrapRef 721 | readonly useClipboard: UnwrapRef 722 | readonly useClipboardItems: UnwrapRef 723 | readonly useCloned: UnwrapRef 724 | readonly useColorMode: UnwrapRef 725 | readonly useConfirmDialog: UnwrapRef 726 | readonly useCounter: UnwrapRef 727 | readonly useCssModule: UnwrapRef 728 | readonly useCssVar: UnwrapRef 729 | readonly useCssVars: UnwrapRef 730 | readonly useCurrentElement: UnwrapRef 731 | readonly useCycleList: UnwrapRef 732 | readonly useDark: UnwrapRef 733 | readonly useDateFormat: UnwrapRef 734 | readonly useDebounce: UnwrapRef 735 | readonly useDebounceFn: UnwrapRef 736 | readonly useDebouncedRefHistory: UnwrapRef 737 | readonly useDeviceMotion: UnwrapRef 738 | readonly useDeviceOrientation: UnwrapRef 739 | readonly useDevicePixelRatio: UnwrapRef 740 | readonly useDevicesList: UnwrapRef 741 | readonly useDisplayMedia: UnwrapRef 742 | readonly useDocumentVisibility: UnwrapRef 743 | readonly useDraggable: UnwrapRef 744 | readonly useDropZone: UnwrapRef 745 | readonly useElementBounding: UnwrapRef 746 | readonly useElementByPoint: UnwrapRef 747 | readonly useElementHover: UnwrapRef 748 | readonly useElementSize: UnwrapRef 749 | readonly useElementVisibility: UnwrapRef 750 | readonly useEventBus: UnwrapRef 751 | readonly useEventListener: UnwrapRef 752 | readonly useEventSource: UnwrapRef 753 | readonly useEyeDropper: UnwrapRef 754 | readonly useFavicon: UnwrapRef 755 | readonly useFetch: UnwrapRef 756 | readonly useFileDialog: UnwrapRef 757 | readonly useFileSystemAccess: UnwrapRef 758 | readonly useFocus: UnwrapRef 759 | readonly useFocusWithin: UnwrapRef 760 | readonly useFps: UnwrapRef 761 | readonly useFullscreen: UnwrapRef 762 | readonly useGamepad: UnwrapRef 763 | readonly useGeolocation: UnwrapRef 764 | readonly useHead: UnwrapRef 765 | readonly useI18n: UnwrapRef 766 | readonly useIdle: UnwrapRef 767 | readonly useImage: UnwrapRef 768 | readonly useInfiniteScroll: UnwrapRef 769 | readonly useIntersectionObserver: UnwrapRef 770 | readonly useInterval: UnwrapRef 771 | readonly useIntervalFn: UnwrapRef 772 | readonly useKeyModifier: UnwrapRef 773 | readonly useLastChanged: UnwrapRef 774 | readonly useLink: UnwrapRef 775 | readonly useLocalStorage: UnwrapRef 776 | readonly useMagicKeys: UnwrapRef 777 | readonly useManualRefHistory: UnwrapRef 778 | readonly useMediaControls: UnwrapRef 779 | readonly useMediaQuery: UnwrapRef 780 | readonly useMemoize: UnwrapRef 781 | readonly useMemory: UnwrapRef 782 | readonly useMounted: UnwrapRef 783 | readonly useMouse: UnwrapRef 784 | readonly useMouseInElement: UnwrapRef 785 | readonly useMousePressed: UnwrapRef 786 | readonly useMutationObserver: UnwrapRef 787 | readonly useNavigatorLanguage: UnwrapRef 788 | readonly useNetwork: UnwrapRef 789 | readonly useNow: UnwrapRef 790 | readonly useObjectUrl: UnwrapRef 791 | readonly useOffsetPagination: UnwrapRef 792 | readonly useOnline: UnwrapRef 793 | readonly usePageLeave: UnwrapRef 794 | readonly useParallax: UnwrapRef 795 | readonly useParentElement: UnwrapRef 796 | readonly usePerformanceObserver: UnwrapRef 797 | readonly usePermission: UnwrapRef 798 | readonly usePointer: UnwrapRef 799 | readonly usePointerLock: UnwrapRef 800 | readonly usePointerSwipe: UnwrapRef 801 | readonly usePreferredColorScheme: UnwrapRef 802 | readonly usePreferredContrast: UnwrapRef 803 | readonly usePreferredDark: UnwrapRef 804 | readonly usePreferredLanguages: UnwrapRef 805 | readonly usePreferredReducedMotion: UnwrapRef 806 | readonly usePrevious: UnwrapRef 807 | readonly useRafFn: UnwrapRef 808 | readonly useRefHistory: UnwrapRef 809 | readonly useResizeObserver: UnwrapRef 810 | readonly useRoute: UnwrapRef 811 | readonly useRouter: UnwrapRef 812 | readonly useScreenOrientation: UnwrapRef 813 | readonly useScreenSafeArea: UnwrapRef 814 | readonly useScriptTag: UnwrapRef 815 | readonly useScroll: UnwrapRef 816 | readonly useScrollLock: UnwrapRef 817 | readonly useSeoMeta: UnwrapRef 818 | readonly useSessionStorage: UnwrapRef 819 | readonly useShare: UnwrapRef 820 | readonly useSlots: UnwrapRef 821 | readonly useSorted: UnwrapRef 822 | readonly useSpeechRecognition: UnwrapRef 823 | readonly useSpeechSynthesis: UnwrapRef 824 | readonly useStepper: UnwrapRef 825 | readonly useStorage: UnwrapRef 826 | readonly useStorageAsync: UnwrapRef 827 | readonly useStyleTag: UnwrapRef 828 | readonly useSupported: UnwrapRef 829 | readonly useSwipe: UnwrapRef 830 | readonly useTemplateRefsList: UnwrapRef 831 | readonly useTextDirection: UnwrapRef 832 | readonly useTextSelection: UnwrapRef 833 | readonly useTextareaAutosize: UnwrapRef 834 | readonly useThrottle: UnwrapRef 835 | readonly useThrottleFn: UnwrapRef 836 | readonly useThrottledRefHistory: UnwrapRef 837 | readonly useTimeAgo: UnwrapRef 838 | readonly useTimeout: UnwrapRef 839 | readonly useTimeoutFn: UnwrapRef 840 | readonly useTimeoutPoll: UnwrapRef 841 | readonly useTimestamp: UnwrapRef 842 | readonly useTitle: UnwrapRef 843 | readonly useToNumber: UnwrapRef 844 | readonly useToString: UnwrapRef 845 | readonly useToggle: UnwrapRef 846 | readonly useTransition: UnwrapRef 847 | readonly useUrlSearchParams: UnwrapRef 848 | readonly useUserMedia: UnwrapRef 849 | readonly useUserStore: UnwrapRef 850 | readonly useVModel: UnwrapRef 851 | readonly useVModels: UnwrapRef 852 | readonly useVibrate: UnwrapRef 853 | readonly useVirtualList: UnwrapRef 854 | readonly useWakeLock: UnwrapRef 855 | readonly useWebNotification: UnwrapRef 856 | readonly useWebSocket: UnwrapRef 857 | readonly useWebWorker: UnwrapRef 858 | readonly useWebWorkerFn: UnwrapRef 859 | readonly useWindowFocus: UnwrapRef 860 | readonly useWindowScroll: UnwrapRef 861 | readonly useWindowSize: UnwrapRef 862 | readonly watch: UnwrapRef 863 | readonly watchArray: UnwrapRef 864 | readonly watchAtMost: UnwrapRef 865 | readonly watchDebounced: UnwrapRef 866 | readonly watchDeep: UnwrapRef 867 | readonly watchEffect: UnwrapRef 868 | readonly watchIgnorable: UnwrapRef 869 | readonly watchImmediate: UnwrapRef 870 | readonly watchOnce: UnwrapRef 871 | readonly watchPausable: UnwrapRef 872 | readonly watchPostEffect: UnwrapRef 873 | readonly watchSyncEffect: UnwrapRef 874 | readonly watchThrottled: UnwrapRef 875 | readonly watchTriggerable: UnwrapRef 876 | readonly watchWithFilter: UnwrapRef 877 | readonly whenever: UnwrapRef 878 | } 879 | } 880 | -------------------------------------------------------------------------------- /src/components.d.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | /* prettier-ignore */ 3 | // @ts-nocheck 4 | // Generated by unplugin-vue-components 5 | // Read more: https://github.com/vuejs/core/pull/3399 6 | export {} 7 | 8 | declare module 'vue' { 9 | export interface GlobalComponents { 10 | RouterLink: typeof import('vue-router')['RouterLink'] 11 | RouterView: typeof import('vue-router')['RouterView'] 12 | TheCounter: typeof import('./components/TheCounter.vue')['default'] 13 | TheFooter: typeof import('./components/TheFooter.vue')['default'] 14 | TheInput: typeof import('./components/TheInput.vue')['default'] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/components/TheCounter.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 16 | -------------------------------------------------------------------------------- /src/components/TheFooter.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 34 | -------------------------------------------------------------------------------- /src/components/TheInput.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 21 | -------------------------------------------------------------------------------- /src/composables/dark.ts: -------------------------------------------------------------------------------- 1 | // these APIs are auto-imported from @vueuse/core 2 | export const isDark = useDark() 3 | export const toggleDark = useToggle(isDark) 4 | export const preferredDark = usePreferredDark() 5 | -------------------------------------------------------------------------------- /src/layouts/404.vue: -------------------------------------------------------------------------------- 1 | 5 | 6 | 19 | -------------------------------------------------------------------------------- /src/layouts/default.vue: -------------------------------------------------------------------------------- 1 | 10 | -------------------------------------------------------------------------------- /src/layouts/home.vue: -------------------------------------------------------------------------------- 1 | 13 | -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | import { ViteSSG } from 'vite-ssg'; 2 | import { setupLayouts } from 'virtual:generated-layouts'; 3 | 4 | import App from './App.vue'; 5 | import type { UserModule } from './types'; 6 | import generatedRoutes from '~pages'; 7 | 8 | import '@unocss/reset/tailwind.css'; 9 | import './styles/main.css'; 10 | import 'uno.css'; 11 | 12 | const routes = setupLayouts(generatedRoutes); 13 | 14 | export const createApp = ViteSSG(App, { routes, base: import.meta.env.BASE_URL }, (ctx) => { 15 | // install all modules under `modules/` 16 | Object.values( 17 | import.meta.glob<{ install: UserModule }>('./modules/*.ts', { eager: true }), 18 | ).forEach((i) => i.install?.(ctx)); 19 | // ctx.app.use(Previewer) 20 | }); 21 | -------------------------------------------------------------------------------- /src/modules/i18n.ts: -------------------------------------------------------------------------------- 1 | import type { Locale } from 'vue-i18n'; 2 | import { createI18n } from 'vue-i18n'; 3 | import { type UserModule } from '~/types'; 4 | 5 | // Import i18n resources 6 | // https://vitejs.dev/guide/features.html#glob-import 7 | // 8 | const i18n = createI18n({ 9 | legacy: false, 10 | locale: '', 11 | messages: {}, 12 | }); 13 | 14 | const localesMap = Object.fromEntries( 15 | Object.entries(import.meta.glob('../../locales/*.yml')).map(([path, loadLocale]) => [ 16 | path.match(/([\w-]*)\.yml$/)?.[1], 17 | loadLocale, 18 | ]), 19 | ) as Record Promise<{ default: Record }>>; 20 | 21 | export const availableLocales = Object.keys(localesMap); 22 | 23 | const loadedLanguages: string[] = []; 24 | 25 | function setI18nLanguage(lang: Locale) { 26 | i18n.global.locale.value = lang as any; 27 | if (typeof document !== 'undefined') document.querySelector('html')?.setAttribute('lang', lang); 28 | return lang; 29 | } 30 | 31 | export async function loadLanguageAsync(lang: string): Promise { 32 | // If the same language 33 | if (i18n.global.locale.value === lang) return setI18nLanguage(lang); 34 | 35 | // If the language was already loaded 36 | if (loadedLanguages.includes(lang)) return setI18nLanguage(lang); 37 | 38 | // If the language hasn't been loaded yet 39 | const messages = await localesMap[lang](); 40 | i18n.global.setLocaleMessage(lang, messages.default); 41 | loadedLanguages.push(lang); 42 | return setI18nLanguage(lang); 43 | } 44 | 45 | export const install: UserModule = ({ app }) => { 46 | app.use(i18n); 47 | loadLanguageAsync('en'); 48 | }; 49 | -------------------------------------------------------------------------------- /src/modules/nprogress.ts: -------------------------------------------------------------------------------- 1 | import NProgress from 'nprogress' 2 | import { type UserModule } from '~/types' 3 | 4 | export const install: UserModule = ({ isClient, router }) => { 5 | if (isClient) { 6 | router.beforeEach((to, from) => { 7 | if (to.path !== from.path) 8 | NProgress.start() 9 | }) 10 | router.afterEach(() => { 11 | NProgress.done() 12 | }) 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/modules/pinia.ts: -------------------------------------------------------------------------------- 1 | import { createPinia } from 'pinia'; 2 | import { type UserModule } from '~/types'; 3 | 4 | // Setup Pinia 5 | // https://pinia.vuejs.org/ 6 | export const install: UserModule = ({ isClient, initialState, app }) => { 7 | const pinia = createPinia(); 8 | app.use(pinia); 9 | // Refer to 10 | if (isClient) pinia.state.value = initialState.pinia || {}; 11 | else initialState.pinia = pinia.state.value; 12 | }; 13 | -------------------------------------------------------------------------------- /src/pages/[...all].vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 10 | 11 | 12 | meta: 13 | layout: 404 14 | 15 | -------------------------------------------------------------------------------- /src/pages/about.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: About 3 | --- 4 | 5 |
6 |
7 |

About

8 |
9 | 10 | ```js 11 | function encode() { 12 | const foo = 'bar'; 13 | console.log(foo); 14 | } 15 | ``` 16 | -------------------------------------------------------------------------------- /src/pages/hi/[name].vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 48 | -------------------------------------------------------------------------------- /src/pages/index.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 43 | 44 | 45 | meta: 46 | layout: home 47 | 48 | -------------------------------------------------------------------------------- /src/shims.d.ts: -------------------------------------------------------------------------------- 1 | declare interface Window { 2 | // extend the window 3 | } 4 | 5 | // with vite-plugin-vue-markdown, markdown files can be treated as Vue components 6 | declare module '*.md' { 7 | import { type DefineComponent } from 'vue' 8 | const component: DefineComponent<{}, {}, any> 9 | export default component 10 | } 11 | 12 | declare module '*.vue' { 13 | import { type DefineComponent } from 'vue' 14 | const component: DefineComponent<{}, {}, any> 15 | export default component 16 | } 17 | -------------------------------------------------------------------------------- /src/stores/user.ts: -------------------------------------------------------------------------------- 1 | import { acceptHMRUpdate, defineStore } from 'pinia' 2 | 3 | export const useUserStore = defineStore('user', () => { 4 | /** 5 | * Current name of the user. 6 | */ 7 | const savedName = ref('') 8 | const previousNames = ref(new Set()) 9 | 10 | const usedNames = computed(() => Array.from(previousNames.value)) 11 | const otherNames = computed(() => usedNames.value.filter(name => name !== savedName.value)) 12 | 13 | /** 14 | * Changes the current name of the user and saves the one that was used 15 | * before. 16 | * 17 | * @param name - new name to set 18 | */ 19 | function setNewName(name: string) { 20 | if (savedName.value) 21 | previousNames.value.add(savedName.value) 22 | 23 | savedName.value = name 24 | } 25 | 26 | return { 27 | setNewName, 28 | otherNames, 29 | savedName, 30 | } 31 | }) 32 | 33 | if (import.meta.hot) 34 | import.meta.hot.accept(acceptHMRUpdate(useUserStore as any, import.meta.hot)) 35 | -------------------------------------------------------------------------------- /src/styles/main.css: -------------------------------------------------------------------------------- 1 | @import './markdown.css'; 2 | 3 | html, 4 | body, 5 | #app { 6 | height: 100%; 7 | margin: 0; 8 | padding: 0; 9 | } 10 | 11 | html.dark { 12 | background: #121212; 13 | color-scheme: dark; 14 | } 15 | 16 | #nprogress { 17 | pointer-events: none; 18 | } 19 | 20 | #nprogress .bar { 21 | background: rgb(13,148,136); 22 | opacity: 0.75; 23 | position: fixed; 24 | z-index: 1031; 25 | top: 0; 26 | left: 0; 27 | width: 100%; 28 | height: 2px; 29 | } 30 | -------------------------------------------------------------------------------- /src/styles/markdown.css: -------------------------------------------------------------------------------- 1 | .prose pre:not(.shiki) { 2 | padding: 0; 3 | } 4 | 5 | .prose .shiki { 6 | font-family: 'DM Mono', monospace; 7 | font-size: 1.2em; 8 | line-height: 1.4; 9 | } 10 | 11 | .prose img { 12 | width: 100%; 13 | } 14 | 15 | .shiki-light { 16 | background: #f8f8f8 !important; 17 | } 18 | .shiki-dark { 19 | background: #0e0e0e !important; 20 | } 21 | 22 | html.dark .shiki-light { 23 | display: none; 24 | } 25 | 26 | html:not(.dark) .shiki-dark { 27 | display: none; 28 | } 29 | -------------------------------------------------------------------------------- /src/types.ts: -------------------------------------------------------------------------------- 1 | import { type ViteSSGContext } from 'vite-ssg' 2 | 3 | export type UserModule = (ctx: ViteSSGContext) => void 4 | -------------------------------------------------------------------------------- /test/__snapshots__/component.test.ts.snap: -------------------------------------------------------------------------------- 1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 | 3 | exports[`TheCounter.vue > should render 1`] = `"
10
"`; 4 | -------------------------------------------------------------------------------- /test/component.test.ts: -------------------------------------------------------------------------------- 1 | import { mount } from '@vue/test-utils' 2 | import { describe, expect, it } from 'vitest' 3 | import TheCounter from '../src/components/TheCounter.vue' 4 | 5 | describe('TheCounter.vue', () => { 6 | it('should render', () => { 7 | const wrapper = mount(TheCounter, { props: { initial: 10 } }) 8 | expect(wrapper.text()).toContain('10') 9 | expect(wrapper.html()).toMatchSnapshot() 10 | }) 11 | 12 | it('should be interactive', async () => { 13 | const wrapper = mount(TheCounter, { props: { initial: 0 } }) 14 | expect(wrapper.text()).toContain('0') 15 | 16 | expect(wrapper.find('.inc').exists()).toBe(true) 17 | 18 | expect(wrapper.find('.dec').exists()).toBe(true) 19 | 20 | await wrapper.get('.inc').trigger('click') 21 | 22 | expect(wrapper.text()).toContain('1') 23 | 24 | await wrapper.get('.dec').trigger('click') 25 | 26 | expect(wrapper.text()).toContain('0') 27 | }) 28 | }) 29 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "module": "ESNext", 5 | "target": "ESNext", 6 | "lib": ["DOM", "ESNext"], 7 | "strict": true, 8 | "esModuleInterop": true, 9 | "jsx": "preserve", 10 | "skipLibCheck": true, 11 | "isolatedModules": true, 12 | "moduleResolution": "node", 13 | "resolveJsonModule": true, 14 | "noUnusedLocals": true, 15 | "strictNullChecks": true, 16 | "allowJs": true, 17 | "forceConsistentCasingInFileNames": true, 18 | "types": [ 19 | "vitest", 20 | "vite/client", 21 | "vue/ref-macros", 22 | "vite-plugin-pages/client", 23 | "vite-plugin-vue-component-preview/client", 24 | "vite-plugin-vue-layouts/client", 25 | "unplugin-vue-macros/macros-global" 26 | ], 27 | "paths": { 28 | "~/*": ["src/*"] 29 | } 30 | }, 31 | "vueCompilerOptions": { 32 | "plugins": ["@vue-macros/volar/define-models", "@vue-macros/volar/define-slots"] 33 | }, 34 | "exclude": ["dist", "node_modules", "cypress", "*.js"] 35 | } 36 | -------------------------------------------------------------------------------- /uno.config.ts: -------------------------------------------------------------------------------- 1 | import { 2 | defineConfig, 3 | presetAttributify, 4 | presetIcons, 5 | presetTypography, 6 | presetUno, 7 | presetWebFonts, 8 | transformerDirectives, 9 | transformerVariantGroup, 10 | } from 'unocss' 11 | 12 | export default defineConfig({ 13 | shortcuts: [ 14 | ['btn', 'px-4 py-1 rounded inline-block bg-teal-700 text-white cursor-pointer !outline-none hover:bg-teal-800 disabled:cursor-default disabled:bg-gray-600 disabled:opacity-50'], 15 | ['icon-btn', 'inline-block cursor-pointer select-none opacity-75 transition duration-200 ease-in-out hover:opacity-100 hover:text-teal-600'], 16 | ], 17 | presets: [ 18 | presetUno(), 19 | presetAttributify(), 20 | presetIcons({ 21 | scale: 1.2, 22 | warn: true, 23 | }), 24 | presetTypography(), 25 | presetWebFonts({ 26 | fonts: { 27 | sans: 'DM Sans', 28 | serif: 'DM Serif Display', 29 | mono: 'DM Mono', 30 | }, 31 | }), 32 | ], 33 | transformers: [ 34 | transformerDirectives(), 35 | transformerVariantGroup(), 36 | ], 37 | safelist: 'prose m-auto text-left'.split(' '), 38 | }) 39 | -------------------------------------------------------------------------------- /vite.config.ts: -------------------------------------------------------------------------------- 1 | import path from 'node:path'; 2 | import { defineConfig } from 'vite'; 3 | import Vue from '@vitejs/plugin-vue'; 4 | import Pages from 'vite-plugin-pages'; 5 | import generateSitemap from 'vite-ssg-sitemap'; 6 | import Layouts from 'vite-plugin-vue-layouts'; 7 | import Components from 'unplugin-vue-components/vite'; 8 | import AutoImport from 'unplugin-auto-import/vite'; 9 | import Markdown from 'vite-plugin-vue-markdown'; 10 | import VueI18n from '@intlify/unplugin-vue-i18n/vite'; 11 | import VueDevTools from 'vite-plugin-vue-devtools'; 12 | import LinkAttributes from 'markdown-it-link-attributes'; 13 | import Unocss from 'unocss/vite'; 14 | import Shiki from 'markdown-it-shiki'; 15 | import VueMacros from 'unplugin-vue-macros/vite'; 16 | import WebfontDownload from 'vite-plugin-webfont-dl'; 17 | 18 | export default defineConfig({ 19 | resolve: { 20 | alias: { 21 | '~/': `${path.resolve(__dirname, 'src')}/`, 22 | }, 23 | }, 24 | 25 | plugins: [ 26 | VueMacros({ 27 | plugins: { 28 | vue: Vue({ 29 | include: [/\.vue$/, /\.md$/], 30 | }), 31 | }, 32 | }), 33 | 34 | Pages({ 35 | extensions: ['vue', 'md'], 36 | }), 37 | 38 | Layouts(), 39 | 40 | AutoImport({ 41 | imports: ['vue', 'vue-router', 'vue-i18n', '@vueuse/head', '@vueuse/core'], 42 | dts: 'src/auto-imports.d.ts', 43 | dirs: ['src/composables', 'src/stores'], 44 | vueTemplate: true, 45 | }), 46 | 47 | Components({ 48 | extensions: ['vue', 'md'], 49 | include: [/\.vue$/, /\.md$/], 50 | dts: 'src/components.d.ts', 51 | }), 52 | 53 | Unocss(), 54 | 55 | Markdown({ 56 | wrapperClasses: 'prose prose-sm m-auto text-left', 57 | headEnabled: true, 58 | markdownItSetup(md) { 59 | md.use(Shiki, { 60 | theme: { 61 | light: 'vitesse-light', 62 | dark: 'vitesse-dark', 63 | }, 64 | }); 65 | md.use(LinkAttributes, { 66 | matcher: (link: string) => /^https?:\/\//.test(link), 67 | attrs: { 68 | target: '_blank', 69 | rel: 'noopener', 70 | }, 71 | }); 72 | }, 73 | }), 74 | 75 | VueI18n({ 76 | runtimeOnly: true, 77 | compositionOnly: true, 78 | fullInstall: true, 79 | include: [path.resolve(__dirname, 'locales/**')], 80 | }), 81 | 82 | WebfontDownload(), 83 | 84 | VueDevTools(), 85 | ], 86 | 87 | test: { 88 | include: ['test/**/*.test.ts'], 89 | environment: 'jsdom', 90 | deps: { 91 | inline: ['@vue', '@vueuse', 'vue-demi'], 92 | }, 93 | }, 94 | 95 | ssr: { 96 | // SSG Vue-i18n workaround 97 | noExternal: [/vue-i18n/], 98 | }, 99 | 100 | ssgOptions: { 101 | script: 'async', 102 | formatting: 'minify', 103 | crittersOptions: { 104 | reduceInlineStyles: false, 105 | }, 106 | onFinished() { 107 | generateSitemap(); 108 | }, 109 | }, 110 | }); 111 | --------------------------------------------------------------------------------