commit
60deda3f73
23 changed files with 4307 additions and 0 deletions
@ -0,0 +1,24 @@ |
|||
# Logs |
|||
logs |
|||
*.log |
|||
npm-debug.log* |
|||
yarn-debug.log* |
|||
yarn-error.log* |
|||
pnpm-debug.log* |
|||
lerna-debug.log* |
|||
|
|||
node_modules |
|||
dist |
|||
dist-ssr |
|||
*.local |
|||
|
|||
# Editor directories and files |
|||
.vscode/* |
|||
!.vscode/extensions.json |
|||
.idea |
|||
.DS_Store |
|||
*.suo |
|||
*.ntvs* |
|||
*.njsproj |
|||
*.sln |
|||
*.sw? |
@ -0,0 +1,3 @@ |
|||
{ |
|||
"recommendations": ["Vue.volar"] |
|||
} |
@ -0,0 +1,5 @@ |
|||
# Vue 3 + TypeScript + Vite |
|||
|
|||
This template should help get you started developing with Vue 3 and TypeScript in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more. |
|||
|
|||
Learn more about the recommended Project Setup and IDE Support in the [Vue Docs TypeScript Guide](https://vuejs.org/guide/typescript/overview.html#project-setup). |
@ -0,0 +1,10 @@ |
|||
/* eslint-disable */ |
|||
/* prettier-ignore */ |
|||
// @ts-nocheck
|
|||
// noinspection JSUnusedGlobalSymbols
|
|||
// Generated by unplugin-auto-import
|
|||
// biome-ignore lint: disable
|
|||
export {} |
|||
declare global { |
|||
|
|||
} |
@ -0,0 +1,15 @@ |
|||
/* eslint-disable */ |
|||
// @ts-nocheck
|
|||
// Generated by unplugin-vue-components
|
|||
// Read more: https://github.com/vuejs/core/pull/3399
|
|||
// biome-ignore lint: disable
|
|||
export {} |
|||
|
|||
/* prettier-ignore */ |
|||
declare module 'vue' { |
|||
export interface GlobalComponents { |
|||
LocaleSwitcher: typeof import('./src/components/LocaleSwitcher/index.vue')['default'] |
|||
ThemeSwitcher: typeof import('./src/components/ThemeSwitcher/index.vue')['default'] |
|||
VanButton: typeof import('vant/es')['Button'] |
|||
} |
|||
} |
@ -0,0 +1,61 @@ |
|||
<!DOCTYPE html> |
|||
<html lang="en"> |
|||
<head> |
|||
<meta charset="UTF-8" /> |
|||
<link rel="icon" type="image/svg+xml" href="/vite.svg" /> |
|||
<meta |
|||
name="viewport" |
|||
content="width=device-width, viewport-fit=cover, initial-scale=1, user-scalable=no, minimal-ui" |
|||
/> |
|||
<title>Vite + Vue + TS</title> |
|||
<script> |
|||
(function flexible(window, document) { |
|||
var docEl = document.documentElement; |
|||
var dpr = window.devicePixelRatio || 1; |
|||
|
|||
// adjust body font size |
|||
function setBodyFontSize() { |
|||
if (document.body) { |
|||
document.body.style.fontSize = 12 * dpr + "px"; |
|||
} else { |
|||
document.addEventListener("DOMContentLoaded", setBodyFontSize); |
|||
} |
|||
} |
|||
setBodyFontSize(); |
|||
|
|||
// set 1rem = viewWidth / 10 |
|||
function setRemUnit() { |
|||
var rem = docEl.clientWidth / 10; |
|||
docEl.style.fontSize = rem + "px"; |
|||
} |
|||
|
|||
setRemUnit(); |
|||
|
|||
// reset rem unit on page resize |
|||
window.addEventListener("resize", setRemUnit); |
|||
window.addEventListener("pageshow", function (e) { |
|||
if (e.persisted) { |
|||
setRemUnit(); |
|||
} |
|||
}); |
|||
|
|||
// detect 0.5px supports |
|||
if (dpr >= 2) { |
|||
var fakeBody = document.createElement("body"); |
|||
var testElement = document.createElement("div"); |
|||
testElement.style.border = ".5px solid transparent"; |
|||
fakeBody.appendChild(testElement); |
|||
docEl.appendChild(fakeBody); |
|||
if (testElement.offsetHeight === 1) { |
|||
docEl.classList.add("hairlines"); |
|||
} |
|||
docEl.removeChild(fakeBody); |
|||
} |
|||
})(window, document); |
|||
</script> |
|||
</head> |
|||
<body> |
|||
<div id="app"></div> |
|||
<script type="module" src="/src/main.ts"></script> |
|||
</body> |
|||
</html> |
File diff suppressed because it is too large
@ -0,0 +1,33 @@ |
|||
{ |
|||
"name": "my-vue-app", |
|||
"private": true, |
|||
"version": "0.0.0", |
|||
"type": "module", |
|||
"scripts": { |
|||
"dev": "vite", |
|||
"build": "vue-tsc -b && vite build", |
|||
"preview": "vite preview" |
|||
}, |
|||
"dependencies": { |
|||
"@tailwindcss/postcss": "^4.1.4", |
|||
"@tailwindcss/vite": "^4.1.4", |
|||
"pinia": "^3.0.2", |
|||
"tailwindcss": "^4.1.4", |
|||
"vant": "^4.9.19", |
|||
"vue": "^3.5.13" |
|||
}, |
|||
"devDependencies": { |
|||
"@types/node": "^22.15.3", |
|||
"@vant/auto-import-resolver": "^1.3.0", |
|||
"@vitejs/plugin-vue": "^5.2.2", |
|||
"@vue/tsconfig": "^0.7.0", |
|||
"postcss": "^8.5.3", |
|||
"postcss-pxtorem": "^6.1.0", |
|||
"typescript": "~5.7.2", |
|||
"unplugin-auto-import": "^19.1.2", |
|||
"unplugin-vue-components": "^28.5.0", |
|||
"vite": "^6.3.1", |
|||
"vue-tsc": "^2.2.8" |
|||
}, |
|||
"packageManager": "[email protected]+sha512.6b865ad4b62a1d9842b61d674a393903b871d9244954f652b8842c2b553c72176b278f64c463e52d40fff8aba385c235c8c9ecf5cc7de4fd78b8bb6d49633ab6" |
|||
} |
File diff suppressed because it is too large
@ -0,0 +1,9 @@ |
|||
export default { |
|||
plugins: { |
|||
"@tailwindcss/postcss": {}, |
|||
"postcss-pxtorem": { |
|||
rootValue: 37.5, |
|||
propList: ["*"], |
|||
}, |
|||
}, |
|||
}; |
After Width: | Height: | Size: 1.5 KiB |
@ -0,0 +1,34 @@ |
|||
<script setup lang="ts"> |
|||
import ThemeSwitcher from "@/components/ThemeSwitcher/index.vue"; |
|||
import { useThemeStore } from "@/stores/theme"; |
|||
const themeStore = useThemeStore(); |
|||
themeStore.initTheme(); |
|||
</script> |
|||
|
|||
<template> |
|||
<div class="text-center text-red-300">欢迎来带我的vue3模板</div> |
|||
<van-button>asdasd</van-button> |
|||
<div> |
|||
<div class="pl-1 text-xs">dasd</div> |
|||
</div> |
|||
<div> |
|||
<ThemeSwitcher /> |
|||
</div> |
|||
</template> |
|||
|
|||
<style scoped> |
|||
.logo { |
|||
height: 6em; |
|||
padding: 1.5em; |
|||
will-change: filter; |
|||
transition: filter 300ms; |
|||
} |
|||
|
|||
.logo:hover { |
|||
filter: drop-shadow(0 0 2em #646cffaa); |
|||
} |
|||
|
|||
.logo.vue:hover { |
|||
filter: drop-shadow(0 0 2em #42b883aa); |
|||
} |
|||
</style> |
@ -0,0 +1,55 @@ |
|||
@import "tailwindcss"; |
|||
|
|||
@theme { |
|||
--spacing: 4px; |
|||
|
|||
--breakpoint-sm: 40rem; |
|||
--breakpoint-md: 48rem; |
|||
--breakpoint-lg: 64rem; |
|||
--breakpoint-xl: 80rem; |
|||
--breakpoint-2xl: 96rem; |
|||
--container-3xs: 16rem; |
|||
--container-2xs: 18rem; |
|||
--container-xs: 20rem; |
|||
--container-sm: 24rem; |
|||
--container-md: 28rem; |
|||
--container-lg: 32rem; |
|||
--container-xl: 36rem; |
|||
--container-2xl: 42rem; |
|||
--container-3xl: 48rem; |
|||
--container-4xl: 56rem; |
|||
--container-5xl: 64rem; |
|||
--container-6xl: 72rem; |
|||
--container-7xl: 80rem; |
|||
|
|||
--text-xs: 0.32rem; |
|||
--text-xs--line-height: calc(1 / 0.32); |
|||
--text-sm: 0.373rem; |
|||
--text-sm--line-height: calc(1.25 / 0.373); |
|||
--text-base: 0.427rem; |
|||
--text-base--line-height: calc(1.5 / 0.427); |
|||
--text-lg: 0.48rem; |
|||
--text-lg--line-height: calc(1.75 / 0.48); |
|||
--text-xl: 0.533rem; |
|||
--text-xl--line-height: calc(1.75 / 0.533); |
|||
/* --text-2xl: 1.5rem; |
|||
--text-2xl--line-height: calc(2 / 1.5); |
|||
--text-3xl: 1.875rem; |
|||
--text-3xl--line-height: calc(2.25 / 1.875); |
|||
--text-4xl: 2.25rem; |
|||
--text-4xl--line-height: calc(2.5 / 2.25); |
|||
--text-5xl: 3rem; |
|||
--text-5xl--line-height: 1; |
|||
--text-6xl: 3.75rem; |
|||
--text-6xl--line-height: 1; |
|||
--text-7xl: 4.5rem; |
|||
--text-7xl--line-height: 1; |
|||
--text-8xl: 6rem; |
|||
--text-8xl--line-height: 1; |
|||
--text-9xl: 8rem; |
|||
--text-9xl--line-height: 1; */ |
|||
} |
|||
|
|||
#app { |
|||
font-size: 14px; |
|||
} |
After Width: | Height: | Size: 496 B |
@ -0,0 +1,21 @@ |
|||
<template> |
|||
<div class="p-4 space-x-2"> |
|||
<button @click="toggleDark" class="px-4 py-2 rounded bg-white dark:bg-black"> |
|||
{{ isDark ? '亮色模式' : '暗黑模式' }} |
|||
</button> |
|||
|
|||
<button @click="setTheme('theme-red')" class="px-4 py-2 rounded bg-primary bg-mint-500 bg-primary"> |
|||
红色主题 |
|||
</button> |
|||
|
|||
<button @click="setTheme('theme-green')" class="px-4 py-2 rounded bg-primary"> |
|||
绿色主题 |
|||
</button> |
|||
</div> |
|||
</template> |
|||
|
|||
<script setup lang="ts"> |
|||
import { useThemeStore } from '@/stores/theme' |
|||
|
|||
const { isDark, toggleDark, setTheme } = useThemeStore() |
|||
</script> |
@ -0,0 +1,10 @@ |
|||
import { createApp } from "vue"; |
|||
import { createPinia } from "pinia"; |
|||
import "@/assets/main.css"; |
|||
import App from "./App.vue"; |
|||
|
|||
const pinia = createPinia(); |
|||
const app = createApp(App); |
|||
|
|||
app.use(pinia); |
|||
app.mount("#app"); |
@ -0,0 +1,51 @@ |
|||
import { defineStore } from "pinia"; |
|||
import { ref } from "vue"; |
|||
|
|||
export const useThemeStore = defineStore("theme", () => { |
|||
const isDark = ref(false); |
|||
const themeClass = ref(""); // 主题色 class,比如 'theme-red'
|
|||
|
|||
function initTheme() { |
|||
const systemPrefersDark = window.matchMedia( |
|||
"(prefers-color-scheme: dark)" |
|||
).matches; |
|||
if ( |
|||
localStorage.theme === "dark" || |
|||
(!("theme" in localStorage) && systemPrefersDark) |
|||
) { |
|||
isDark.value = true; |
|||
document.documentElement.classList.add("dark"); |
|||
} else { |
|||
isDark.value = false; |
|||
document.documentElement.classList.remove("dark"); |
|||
} |
|||
} |
|||
|
|||
function toggleDark() { |
|||
isDark.value = !isDark.value; |
|||
localStorage.theme = isDark.value ? "dark" : "light"; |
|||
if (isDark.value) { |
|||
document.documentElement.classList.add("dark"); |
|||
} else { |
|||
document.documentElement.classList.remove("dark"); |
|||
} |
|||
} |
|||
|
|||
function setTheme(theme: string) { |
|||
themeClass.value = theme; |
|||
const html = document.documentElement; |
|||
|
|||
// 移除以前的 theme-xxx 类
|
|||
html.classList.forEach((cls) => { |
|||
if (cls.startsWith("theme-")) { |
|||
html.classList.remove(cls); |
|||
} |
|||
}); |
|||
// 加上新的
|
|||
if (theme) { |
|||
html.classList.add(theme); |
|||
} |
|||
} |
|||
|
|||
return { isDark, themeClass, toggleDark, setTheme, initTheme }; |
|||
}); |
@ -0,0 +1 @@ |
|||
/// <reference types="vite/client" />
|
@ -0,0 +1,18 @@ |
|||
{ |
|||
"extends": "@vue/tsconfig/tsconfig.dom.json", |
|||
"compilerOptions": { |
|||
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", |
|||
|
|||
/* Linting */ |
|||
"strict": true, //开启所有严格检查模式 |
|||
"noUnusedLocals": true, //不能有没用到的局部变量 |
|||
"noUnusedParameters": true, // 不能有没用到的函数参数 |
|||
"noFallthroughCasesInSwitch": true, //switch 语句必须用 break 或 return |
|||
"noUncheckedSideEffectImports": true, //禁止直接导入有副作用的模块(除非显式标注) |
|||
"baseUrl": "./", |
|||
"paths": { |
|||
"@/*": ["src/*"] |
|||
} |
|||
}, |
|||
"include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"] |
|||
} |
@ -0,0 +1,7 @@ |
|||
{ |
|||
"files": [], |
|||
"references": [ |
|||
{ "path": "./tsconfig.app.json" }, |
|||
{ "path": "./tsconfig.node.json" } |
|||
] |
|||
} |
@ -0,0 +1,24 @@ |
|||
{ |
|||
"compilerOptions": { |
|||
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", |
|||
"target": "ES2022", |
|||
"lib": ["ES2023"], |
|||
"module": "ESNext", |
|||
"skipLibCheck": true, |
|||
|
|||
/* Bundler mode */ |
|||
"moduleResolution": "bundler", |
|||
"allowImportingTsExtensions": true, |
|||
"isolatedModules": true, |
|||
"moduleDetection": "force", |
|||
"noEmit": true, |
|||
|
|||
/* Linting */ |
|||
"strict": true, |
|||
"noUnusedLocals": true, |
|||
"noUnusedParameters": true, |
|||
"noFallthroughCasesInSwitch": true, |
|||
"noUncheckedSideEffectImports": true |
|||
}, |
|||
"include": ["vite.config.ts"] |
|||
} |
@ -0,0 +1,26 @@ |
|||
import { defineConfig } from "vite"; |
|||
import vue from "@vitejs/plugin-vue"; |
|||
import tailwindcss from "@tailwindcss/vite"; |
|||
import path from "path"; |
|||
import AutoImport from "unplugin-auto-import/vite"; |
|||
import Components from "unplugin-vue-components/vite"; |
|||
import { VantResolver } from "@vant/auto-import-resolver"; |
|||
|
|||
// https://vite.dev/config/
|
|||
export default defineConfig({ |
|||
plugins: [ |
|||
vue(), |
|||
tailwindcss(), |
|||
AutoImport({ |
|||
resolvers: [VantResolver()], |
|||
}), |
|||
Components({ |
|||
resolvers: [VantResolver()], |
|||
}), |
|||
], |
|||
resolve: { |
|||
alias: { |
|||
"@": path.resolve(__dirname, "src"), |
|||
}, |
|||
}, |
|||
}); |
Loading…
Reference in new issue