├── .env ├── src ├── plugins │ ├── index.ts │ ├── vue-query.ts │ └── dayjs.ts ├── static │ ├── logo.png │ ├── vue.svg │ └── vite.svg ├── store │ ├── modules │ │ ├── index.ts │ │ ├── auth │ │ │ └── index.ts │ │ ├── count │ │ │ └── index.ts │ │ └── app │ │ │ └── index.ts │ └── index.ts ├── styles │ ├── reset.css │ └── variables.scss ├── pages │ ├── count │ │ └── count.vue │ └── index │ │ └── index.vue ├── theme.json ├── api │ └── index.ts ├── composables │ └── useToken.ts ├── components │ └── Counter.vue ├── constants │ └── index.ts ├── pages.json ├── utils │ ├── shared.ts │ └── is.ts ├── main.ts ├── layouts │ └── default.vue ├── App.vue ├── manifest.json ├── service │ ├── types.ts │ ├── index.ts │ └── helper.ts └── uni.scss ├── .npmrc ├── typings ├── shime-uni.d.ts ├── common.d.ts └── vite-env.d.ts ├── .vscode ├── extensions.json └── settings.json ├── .editorconfig ├── .stylelintignore ├── .lintstagedrc.cjs ├── netlify.toml ├── .env.production ├── .env.development ├── .gitignore ├── renovate.json ├── eslint.config.mjs ├── index.html ├── LICENSE ├── .stylelintcache ├── pages.config.ts ├── tsconfig.json ├── .stylelintrc ├── vite.config.ts ├── uno.config.ts ├── README.md ├── manifest.config.ts ├── commitlint.config.js └── package.json /.env: -------------------------------------------------------------------------------- 1 | VITE_APP_TITLE='' 2 | #服务启动端口 3 | VITE_PORT=5777 4 | 5 | -------------------------------------------------------------------------------- /src/plugins/index.ts: -------------------------------------------------------------------------------- 1 | export * from './dayjs' 2 | export * from './vue-query' 3 | -------------------------------------------------------------------------------- /src/static/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yang1206/uniapp-template/HEAD/src/static/logo.png -------------------------------------------------------------------------------- /src/store/modules/index.ts: -------------------------------------------------------------------------------- 1 | export * from './count' 2 | export * from './app' 3 | export * from './auth' 4 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | # public-hoist-pattern[]=@vue* 2 | strict-peer-dependencies=false 3 | auto-install-peers=true 4 | shamefully-hoist=true 5 | -------------------------------------------------------------------------------- /typings/shime-uni.d.ts: -------------------------------------------------------------------------------- 1 | export {} 2 | 3 | declare module "vue" { 4 | type Hooks = App.AppInstance & Page.PageInstance; 5 | interface ComponentCustomOptions extends Hooks {} 6 | } -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "dbaeumer.vscode-eslint", 4 | "uni-helper.uni-helper-vscode", 5 | "vue.volar", 6 | "antfu.unocss" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true -------------------------------------------------------------------------------- /typings/common.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 路由类型定义 3 | */ 4 | declare interface Route { 5 | path: string; 6 | name?: string; 7 | fullPath?: string; 8 | query: Query; 9 | [key: string]: any; 10 | } 11 | -------------------------------------------------------------------------------- /src/styles/reset.css: -------------------------------------------------------------------------------- 1 | html, 2 | body, 3 | #app { 4 | height: 100%; 5 | padding: 0; 6 | margin: 0; 7 | } 8 | 9 | html{ 10 | font-size:8px; 11 | } 12 | 13 | html.dark { 14 | background: #121212; 15 | } -------------------------------------------------------------------------------- /.stylelintignore: -------------------------------------------------------------------------------- 1 | dist 2 | es 3 | lib 4 | css 5 | example 6 | public 7 | cache 8 | node_modules 9 | .husky 10 | 11 | docs/.vitepress/theme 12 | 13 | *.js 14 | *.cjs 15 | *.mjs 16 | *.ts 17 | *.tsx 18 | *.svg 19 | *.gif 20 | *.md 21 | -------------------------------------------------------------------------------- /src/store/index.ts: -------------------------------------------------------------------------------- 1 | import { createPinia } from 'pinia' 2 | import type { App } from 'vue' 3 | 4 | export const pinia = createPinia() 5 | export async function setupStore(app: App) { 6 | app.use(pinia) 7 | } 8 | 9 | export * from './modules' 10 | -------------------------------------------------------------------------------- /.lintstagedrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | '*.{js,cjs,mjs,jsx,ts,cts,mts,tsx,vue}': 'eslint --fix --cache', 3 | '*.{scss,css,vue}': 'stylelint --fix --allow-empty-input', 4 | '*.{ts,cts,mts,tsx,vue}': () => 'vue-tsc --noEmit -p tsconfig.json --composite false', 5 | } 6 | -------------------------------------------------------------------------------- /netlify.toml: -------------------------------------------------------------------------------- 1 | [build.environment] 2 | NPM_FLAGS = "--version" 3 | NODE_VERSION = "16" 4 | 5 | [build] 6 | publish = "dist/build/h5" 7 | command = "npx pnpm i --store=node_modules/.pnpm-store && npx pnpm run build:h5" 8 | 9 | [[redirects]] 10 | from = "/*" 11 | to = "/index.html" 12 | status = 200 -------------------------------------------------------------------------------- /src/plugins/vue-query.ts: -------------------------------------------------------------------------------- 1 | import { VueQueryPlugin } from '@tanstack/vue-query' 2 | import type { Plugin } from 'vue' 3 | import { vueQueryPluginOptions } from '@/service' 4 | 5 | export const vueQueryPlugin: Plugin = { 6 | install: (app) => { 7 | app.use(VueQueryPlugin, vueQueryPluginOptions) 8 | }, 9 | } 10 | -------------------------------------------------------------------------------- /src/pages/count/count.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | { 9 | "style": { 10 | "navigationStyle": "default", 11 | "navigationBarTitleText": "Count" 12 | } 13 | } 14 | 15 | -------------------------------------------------------------------------------- /src/plugins/dayjs.ts: -------------------------------------------------------------------------------- 1 | import dayjs from 'dayjs' 2 | import customParseFormat from 'dayjs/plugin/customParseFormat' 3 | import type { Plugin } from 'vue' 4 | 5 | /** 6 | * Installs the customParseFormat extension for dayjs. 7 | */ 8 | export const dayjsPlugin: Plugin = { 9 | install: () => { 10 | dayjs.extend(customParseFormat) 11 | }, 12 | } 13 | -------------------------------------------------------------------------------- /.env.production: -------------------------------------------------------------------------------- 1 | ENV = "production" 2 | 3 | # 资源公共路径,需要以 /开头和结尾 4 | VITE_PUBLIC_PATH = '/' 5 | 6 | # 是否hash路由模式 7 | VITE_USE_HASH = false 8 | 9 | # axios base api 10 | VITE_BASE_API = 'https://api.github.com/repos/yang1206' 11 | 12 | 13 | 14 | 15 | # 是否启用代理(只对本地vite server生效,开启MOCK时可关闭代理) 16 | VITE_USE_PROXY = false 17 | 18 | # 代理类型(跟启动和构建环境无关) 'dev' | 'test' | 'prod' 19 | VITE_PROXY_TYPE = 'test' -------------------------------------------------------------------------------- /.env.development: -------------------------------------------------------------------------------- 1 | ENV = "development" 2 | 3 | VITE_ALOVA_TIPS=0 4 | # 资源公共路径,需要以 /开头和结尾 5 | VITE_PUBLIC_PATH = '/' 6 | 7 | # 是否hash路由模式 8 | VITE_USE_HASH = false 9 | 10 | # base api 11 | VITE_BASE_API = 'https://api.github.com' 12 | 13 | 14 | 15 | 16 | # 是否启用代理(只对本地vite server生效,开启MOCK时可关闭代理) 17 | VITE_USE_PROXY = false 18 | 19 | # 代理类型(跟启动和构建环境无关) 'dev' | 'test' | 'prod' 20 | VITE_PROXY_TYPE = 'test' 21 | 22 | -------------------------------------------------------------------------------- /src/store/modules/auth/index.ts: -------------------------------------------------------------------------------- 1 | import { defineStore } from 'pinia' 2 | import { useToken } from '@/composables/useToken' 3 | import { DefaultToken } from '@/constants' 4 | 5 | export const useAuthStore = defineStore('auth', () => { 6 | const token = useToken() 7 | const setToken = (newToken = DefaultToken) => { 8 | token.value = newToken 9 | } 10 | return { 11 | token, 12 | setToken, 13 | } 14 | }) 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | typings/auto-import.d.ts 11 | typings/uni-pages.d.ts 12 | typings/components.d.ts 13 | 14 | 15 | node_modules 16 | .DS_Store 17 | dist 18 | *.local 19 | coverage 20 | .eslintcache 21 | # Editor directories and files 22 | .idea 23 | *.suo 24 | *.ntvs* 25 | *.njsproj 26 | *.sln 27 | *.sw? 28 | -------------------------------------------------------------------------------- /src/theme.json: -------------------------------------------------------------------------------- 1 | { 2 | "dark": { 3 | "navBgColor": "#373739", 4 | "navTxtStyle": "white", 5 | "bgColor": "#000", 6 | "bgTxtStyle": "light", 7 | "bgColorTop": "#000", 8 | "bgColorBottom": "#000" 9 | }, 10 | "light": { 11 | "navBgColor": "#FFFFFF", 12 | "navTxtStyle": "black", 13 | "bgColor": "#F3F4F6", 14 | "bgTxtStyle": "dark", 15 | "bgColorTop": "#F3F4F6", 16 | "bgColorBottom": "#F3F4F6" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/api/index.ts: -------------------------------------------------------------------------------- 1 | import type { QueryOptions } from '@tanstack/vue-query' 2 | import { unInstance } from '@/service' 3 | 4 | interface GITHUB { 5 | owner: { 6 | archive_url: string 7 | login: string 8 | } 9 | full_name: string 10 | html_url: string 11 | } 12 | 13 | export function fetchGitHubRepo(repo: string) { 14 | return { 15 | queryKey: [repo, 'repos'], 16 | queryFn: async () => (await unInstance.get(`repos/${repo}`)).data, 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/store/modules/count/index.ts: -------------------------------------------------------------------------------- 1 | import { defineStore } from 'pinia' 2 | 3 | export const useCounterStore = defineStore('counter', () => { 4 | const count = ref(0) 5 | function inc() { 6 | count.value += 1 7 | } 8 | function dec() { 9 | count.value -= 1 10 | } 11 | async function asyncInc() { 12 | setTimeout(() => { 13 | inc() 14 | }, 300) 15 | } 16 | return { 17 | count, 18 | inc, 19 | dec, 20 | asyncInc, 21 | } 22 | }) 23 | -------------------------------------------------------------------------------- /src/static/vue.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": [ 4 | "config:base", 5 | ":automergePatch", 6 | ":automergeTypes", 7 | ":automergeTesters", 8 | ":automergeLinters", 9 | ":rebaseStalePrs", 10 | ":semanticCommits", 11 | "schedule:quarterly" 12 | ], 13 | "packageRules": [ 14 | { 15 | "updateTypes": [ 16 | "major" 17 | ], 18 | "labels": [ 19 | "UPDATE-MAJOR" 20 | ] 21 | } 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import uniHelper from '@uni-helper/eslint-config' 2 | 3 | export default uniHelper( 4 | { 5 | uni: true, 6 | uniJson: true, 7 | unocss: true, 8 | vue: { 9 | overrides: { 10 | 'vue/custom-event-name-casing': ['kebab-case' | 'camelCase'], 11 | 'vue/singleline-html-element-content-newline': 'off', 12 | 'vue/multiline-html-element-content-newline': 'off', 13 | 'vue/max-attributes-per-line': [ 14 | 2, 15 | { 16 | multiline: 1, 17 | singleline: 3, 18 | }, 19 | ], 20 | }, 21 | }, 22 | }, 23 | ) 24 | -------------------------------------------------------------------------------- /src/composables/useToken.ts: -------------------------------------------------------------------------------- 1 | import { useStorageAsync } from '@uni-helper/uni-use' 2 | 3 | // import type { RemovableRef } from '@vueuse/core' 4 | import type { RemovableRef } from '@vueuse/core' 5 | import { DefaultToken, TokenKey } from '@/constants' 6 | 7 | /** 8 | * Generates a function comment for the given function body. 9 | * 10 | * @param {string} initialToken - the initial token value (optional, default: DefaultToken) 11 | * @return {RemovableRef} the token value 12 | */ 13 | export function useToken(initialToken: string = DefaultToken): RemovableRef { 14 | const token = useStorageAsync(TokenKey, initialToken) 15 | return token 16 | } 17 | -------------------------------------------------------------------------------- /src/components/Counter.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 25 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/constants/index.ts: -------------------------------------------------------------------------------- 1 | import { pascalCase } from 'change-case' 2 | import pkg from '@/../package.json' 3 | 4 | const ViteMode = import.meta.env.VITE_MODE || 'production' 5 | const PascalCaseViteMode = pascalCase(ViteMode) 6 | 7 | export { default as pkg } from '@/../package.json' 8 | 9 | // 请求 10 | /** 默认请求基地址 */ 11 | export const DefaultBaseUrl 12 | = import.meta.env.VITE_BASE_API || 'https://jsonplaceholder.typicode.com/' 13 | /** 默认请求头 */ 14 | export const DefaultHeaders = { 15 | 'Accept': 'application/json', 16 | 'Content-Type': 'application/json; charset=utf-8', 17 | 'X-Version': `${pkg.name}/${pkg.version}`, 18 | } 19 | 20 | /** 登录态键 */ 21 | export const TokenKey = `token${PascalCaseViteMode}` 22 | /** 默认登录态 */ 23 | export const DefaultToken = '' 24 | 25 | export const ThemeKey = `theme${PascalCaseViteMode}` 26 | -------------------------------------------------------------------------------- /src/pages.json: -------------------------------------------------------------------------------- 1 | {"pages":[{"path":"pages/index/index","type":"home","style":{"navigationStyle":"default","navigationBarTitleText":"Home"}},{"path":"pages/count/count","type":"page","style":{"navigationStyle":"default","navigationBarTitleText":"Count"}}],"globalStyle":{"navigationBarBackgroundColor":"@navBgColor","navigationBarTextStyle":"@navTxtStyle","navigationBarTitleText":"uniapp-vite-template","backgroundColor":"@bgColor","backgroundTextStyle":"@bgTxtStyle","backgroundColorTop":"@bgColorTop","backgroundColorBottom":"@bgColorBottom","navigationStyle":"custom"},"tabBar":{"custom":true,"color":"rgba(255, 255, 255, 0)","selectedColor":"rgba(255, 255, 255, 0)","backgroundColor":"rgba(255, 255, 255, 0)","borderStyle":"rgb(255,255,255,0)","list":[{"pagePath":"pages/index/index","text":"Home"},{"pagePath":"pages/count/count","text":"Count"}]},"subPackages":[]} 2 | -------------------------------------------------------------------------------- /typings/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | type ProxyType = 'dev' | 'test' | 'prod' 4 | 5 | interface ProxyConfig { 6 | /** 匹配代理的前缀,接口地址匹配到此前缀将代理的target地址 */ 7 | prefix: string 8 | /** 代理目标地址,后端真实接口地址 */ 9 | target: string 10 | } 11 | 12 | interface ImportMetaEnv { 13 | readonly VITE_APP_TITLE: string 14 | readonly VITE_PORT: number 15 | readonly VITE_USE_PROXY?: boolean 16 | readonly VITE_PROXY_TYPE?: ProxyType 17 | readonly VITE_USE_HASH: 'true' | 'false' 18 | readonly VITE_BASE_API: string 19 | // 更多环境变量... 20 | } 21 | 22 | interface ImportMeta { 23 | readonly env: ImportMetaEnv 24 | } 25 | 26 | declare module '*.vue' { 27 | import type { DefineComponent } from 'vue' 28 | // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types 29 | const component: DefineComponent<{}, {}, any> 30 | export default component 31 | } 32 | -------------------------------------------------------------------------------- /src/utils/shared.ts: -------------------------------------------------------------------------------- 1 | // 防止快速点击 2 | let lastClickTime = 0 3 | 4 | export function isFastClick(num = 1000) { 5 | const time = new Date().getTime() 6 | if (time - lastClickTime > num) 7 | return false 8 | 9 | lastClickTime = time 10 | return true 11 | } 12 | 13 | // 解析 path 14 | export function parseUrl(fullPath: string) { 15 | const [path, queryStr] = fullPath.split('?') 16 | const name = path.slice(path.lastIndexOf('/') + 1) 17 | const query: { [key: string]: unknown } = {} 18 | queryStr 19 | ?.split('&') 20 | .map(i => i.split('=')) 21 | .forEach(i => (query[i[0]] = i[1])) 22 | return { 23 | name, 24 | path, 25 | query, 26 | } 27 | } 28 | 29 | // 还原url 30 | export function restoreUrl(path: string, query: { [key: string]: unknown }) { 31 | let count = 0 32 | for (const key in query) { 33 | path += `${count === 0 ? '?' : '&'}${key}=${query[key]}` 34 | count += 1 35 | } 36 | return path 37 | } 38 | -------------------------------------------------------------------------------- /src/store/modules/app/index.ts: -------------------------------------------------------------------------------- 1 | interface MenuButtonBoundingClientRect { 2 | width: number 3 | height: number 4 | top: number 5 | left: number 6 | right: number 7 | bottom: number 8 | } 9 | 10 | export const useAppStore = defineStore( 11 | 'app', 12 | () => { 13 | const darkMode = ref(false) 14 | const statusBarHeight = ref(0) 15 | const menuButtonBounding = ref() 16 | const customBarHeight = computed( 17 | () => !menuButtonBounding.value 18 | ? 0 19 | : menuButtonBounding.value.bottom + menuButtonBounding.value.top - statusBarHeight.value, 20 | ) 21 | 22 | // #ifdef H5 23 | watch(darkMode, (isDark) => { 24 | isDark ? document.documentElement.classList.add('dark') : document.documentElement.classList.remove('dark') 25 | }, { 26 | immediate: true, 27 | }) 28 | // #endif 29 | 30 | return { 31 | darkMode, 32 | statusBarHeight, 33 | customBarHeight, 34 | menuButtonBounding, 35 | } 36 | }, 37 | ) 38 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 yang1206 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /.stylelintcache: -------------------------------------------------------------------------------- 1 | [{"/Users/yangjunwei/codes/frontend/web/Project_Learn/mini-program/uniapp-vite/src/App.vue":"1","/Users/yangjunwei/codes/frontend/web/Project_Learn/mini-program/uniapp-vite/src/uni.scss":"2","/Users/yangjunwei/codes/frontend/web/Project_Learn/mini-program/uniapp-vite/src/styles/reset.css":"3","/Users/yangjunwei/codes/frontend/web/Project_Learn/mini-program/uniapp-vite/src/styles/variables.scss":"4","/Users/yangjunwei/codes/frontend/web/Project_Learn/mini-program/uniapp-vite/src/components/Counter.vue":"5","/Users/yangjunwei/codes/frontend/web/Project_Learn/mini-program/uniapp-vite/src/layouts/default.vue":"6","/Users/yangjunwei/codes/frontend/web/Project_Learn/mini-program/uniapp-vite/src/pages/count/count.vue":"7","/Users/yangjunwei/codes/frontend/web/Project_Learn/mini-program/uniapp-vite/src/pages/index/index.vue":"8"},{"size":1431,"mtime":1698888811952,"hashOfConfig":"9"},{"size":2251,"mtime":1700919780749,"hashOfConfig":"9"},{"size":127,"mtime":1700919780791,"hashOfConfig":"9"},{"size":1675,"mtime":1700919780791,"hashOfConfig":"9"},{"size":567,"mtime":1686929737039,"hashOfConfig":"9"},{"size":1335,"mtime":1694656381072,"hashOfConfig":"9"},{"size":372,"mtime":1700573207880,"hashOfConfig":"9"},{"size":1148,"mtime":1700919780807,"hashOfConfig":"9"},"45xzdr"] -------------------------------------------------------------------------------- /pages.config.ts: -------------------------------------------------------------------------------- 1 | import { isMpWeixin } from '@uni-helper/uni-env' 2 | import { defineUniPages } from '@uni-helper/vite-plugin-uni-pages' 3 | 4 | export default defineUniPages({ 5 | // 你也可以定义 pages 字段,它具有最高的优先级。 6 | pages: [ 7 | { 8 | path: 'pages/index/index', 9 | }, 10 | ], 11 | globalStyle: { 12 | navigationBarBackgroundColor: '@navBgColor', 13 | navigationBarTextStyle: '@navTxtStyle', 14 | navigationBarTitleText: 'uniapp-vite-template', 15 | backgroundColor: '@bgColor', 16 | backgroundTextStyle: '@bgTxtStyle', 17 | backgroundColorTop: '@bgColorTop', 18 | backgroundColorBottom: '@bgColorBottom', 19 | navigationStyle: 'custom', 20 | }, 21 | tabBar: { 22 | // 支付宝小程序自定义需要特殊处理 23 | custom: true, 24 | color: `rgba(${255}, ${255}, ${255}, ${0})` as any, 25 | selectedColor: `rgba(${255}, ${255}, ${255}, ${0})` as any, 26 | backgroundColor: `rgba(${255}, ${255}, ${255}, ${0})` as any, 27 | borderStyle: isMpWeixin ? 'white' : 'rgb(255,255,255,0)' as any, 28 | list: [ 29 | { 30 | pagePath: 'pages/index/index', 31 | text: 'Home', 32 | }, 33 | { 34 | pagePath: 'pages/count/count', 35 | text: 'Count', 36 | }, 37 | ], 38 | }, 39 | 40 | }) 41 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "jsx": "preserve", 5 | "jsxImportSource": "vue", 6 | "lib": [ 7 | "DOM", 8 | "DOM.Iterable", 9 | "ESNext" 10 | ], 11 | "useDefineForClassFields": true, 12 | "baseUrl": ".", 13 | "module": "ESNext", 14 | "moduleResolution": "Bundler", 15 | "paths": { 16 | "@/*": [ 17 | "src/*" 18 | ], 19 | "~/*": [ 20 | "./*" 21 | ] 22 | }, 23 | "resolveJsonModule": true, 24 | "types": [ 25 | "vite/client", 26 | "@dcloudio/types", 27 | "@mini-types/alipay", 28 | "miniprogram-api-typings", 29 | "unplugin-vue-macros/macros-global", 30 | "nutui-uniapp/global.d.ts", 31 | "unplugin-icons/types/vue", 32 | "type-fest", 33 | "@uni-helper/uni-types" 34 | ], 35 | "strict": true, 36 | "noImplicitThis": true, 37 | "esModuleInterop": true, 38 | "forceConsistentCasingInFileNames": true, 39 | "verbatimModuleSyntax": true, 40 | "skipLibCheck": true 41 | }, 42 | "vueCompilerOptions": { 43 | "plugins": [ 44 | "@uni-helper/uni-types/volar-plugin" 45 | ] 46 | }, 47 | "include": [ 48 | "typings/components.d.ts", 49 | "**/*.d.ts", 50 | "**/*.tsx", 51 | "**/*.ts", 52 | "**/*.vue", 53 | "package.json" 54 | ] 55 | } 56 | -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | // check https://wechat-miniprogram.github.io/miniprogram-compat/ 2 | // import 'core-js/actual'; 3 | // import 'core-js/actual/structured-clone' 4 | 5 | // import 'core-js/actual/array/flat'; // since 2.16.1 6 | // import 'core-js/actual/array/flat-map'; // since 2.16.1 7 | // import 'core-js/actual/object/entries'; // since 2.16.1 8 | // import 'core-js/actual/object/from-entries'; // since 2.16.1 9 | // import 'core-js/actual/object/values'; // since 2.16.1 10 | // import 'core-js/actual/promise'; // since 2.11.0 11 | // import 'core-js/actual/promise/all-settled'; // since 2.16.1 12 | // import 'core-js/actual/promise/finally'; // since 2.16.1 13 | // import 'core-js/actual/string/pad-end'; // since 2.16.1 14 | // import 'core-js/actual/string/pad-start'; // since 2.16.1 15 | // import 'core-js/actual/string/replace-all' 16 | 17 | import { setupStore } from '@/store' 18 | // since 2.16.1 but consider other platforms 19 | // import 'core-js/actual/string/trim-end' 20 | // import 'core-js/actual/string/trim-start' 21 | import { createSSRApp } from 'vue' 22 | import App from './App.vue' 23 | import { dayjsPlugin, vueQueryPlugin } from './plugins' 24 | import 'uno.css' 25 | import '@/styles/reset.css' 26 | 27 | export function createApp() { 28 | const app = createSSRApp(App).use(dayjsPlugin).use(vueQueryPlugin) 29 | setupStore(app) 30 | return { 31 | app, 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/pages/index/index.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 36 | 37 | 38 | { 39 | "style": { 40 | "navigationStyle": "default", 41 | "navigationBarTitleText": "Home" 42 | } 43 | } 44 | 45 | 46 | 55 | -------------------------------------------------------------------------------- /src/static/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/layouts/default.vue: -------------------------------------------------------------------------------- 1 | 30 | 31 | 46 | 47 | 53 | -------------------------------------------------------------------------------- /.stylelintrc: -------------------------------------------------------------------------------- 1 | { 2 | "defaultSeverity": "error", 3 | "extends": [ 4 | "stylelint-config-standard", 5 | "stylelint-config-standard-scss", 6 | "stylelint-config-recommended-vue", 7 | "stylelint-config-html", 8 | "stylelint-config-recess-order" 9 | ], 10 | "plugins": [ 11 | "stylelint-order" 12 | ], 13 | "rules": { 14 | "selector-class-pattern": [ 15 | "^([#a-z][$#{}a-z0-9]*)((-{1,2}|_{2})[$#{}a-z0-9]+)*$", 16 | { 17 | "message": "Expected class selector to be kebab-case" 18 | } 19 | ], 20 | "selector-pseudo-class-no-unknown": [ 21 | true, 22 | { 23 | "ignorePseudoClasses": [ 24 | "::v-deep", 25 | "deep", 26 | "v-deep" 27 | ] 28 | } 29 | ], 30 | "selector-type-no-unknown": [ 31 | true, 32 | { 33 | "ignoreTypes": [ 34 | "page", 35 | "rich-text", 36 | "scroll-view" 37 | ] 38 | } 39 | ], 40 | "unit-no-unknown":[ 41 | true, 42 | { 43 | "ignoreUnits": ["rpx","upx"] 44 | } 45 | ], 46 | "no-descending-specificity": null, 47 | "no-empty-source": null, 48 | "keyframes-name-pattern": "^[a-z]+([A-Z][a-z]*)*$" 49 | }, 50 | "ignoreFiles": [ 51 | "node_modules", 52 | "dist", 53 | "public", 54 | "output", 55 | "coverage", 56 | "temp", 57 | "*.js", 58 | "*.cjs", 59 | "*.mjs", 60 | "*.ts", 61 | "*.tsx", 62 | "*.svg", 63 | "*.gif", 64 | "*.md" 65 | ] 66 | } 67 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 39 | 40 | 43 | -------------------------------------------------------------------------------- /vite.config.ts: -------------------------------------------------------------------------------- 1 | import type { ConfigEnv } from 'vite' 2 | import process from 'node:process' 3 | import { defineConfig, loadEnv } from 'vite' 4 | import { createViteProxy } from './build/config' 5 | import { setupVitePlugins } from './build/plugins' 6 | import { convertEnv, getRootPath, getSrcPath } from './build/utils' 7 | 8 | // https://vitejs.dev/config/ 9 | export default defineConfig(async (configEnv: ConfigEnv) => { 10 | const srcPath = getSrcPath() 11 | const rootPath = getRootPath() 12 | const viteEnv = convertEnv(loadEnv(configEnv.mode, process.cwd())) 13 | const { VITE_PORT, VITE_USE_PROXY, VITE_PROXY_TYPE } = viteEnv 14 | return { 15 | plugins: await setupVitePlugins(), 16 | server: { 17 | host: '0.0.0.0', 18 | port: VITE_PORT, 19 | open: false, 20 | proxy: createViteProxy(VITE_USE_PROXY, VITE_PROXY_TYPE as ProxyType), 21 | }, 22 | envPrefix: ['VITE_', 'UNI_'], 23 | build: { 24 | target: 'es6', 25 | cssTarget: 'chrome61', 26 | reportCompressedSize: false, 27 | sourcemap: false, 28 | chunkSizeWarningLimit: 1024, // chunk 大小警告的限制(单位kb) 29 | commonjsOptions: { 30 | ignoreTryCatch: false, 31 | }, 32 | }, 33 | optimizeDeps: { 34 | exclude: ['vue-demi'], 35 | }, 36 | css: { 37 | preprocessorOptions: { 38 | scss: { 39 | api: 'modern-compiler', 40 | additionalData: `@import '@/styles/variables.scss';`, 41 | }, 42 | }, 43 | }, 44 | resolve: { 45 | alias: { 46 | '~': rootPath, 47 | '@': srcPath, 48 | }, 49 | }, 50 | } 51 | }) 52 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "explorer.fileNesting.patterns": { 3 | "vite.config.*": "pages.config.*, manifest.config.*, unocss.config.*, volar.config.*, *.env, .env.*" 4 | }, 5 | "typescript.tsdk": "node_modules/typescript/lib", 6 | // "editor.defaultFormatter": "esbenp.prettier-vscode", 7 | "references.preferredLocation": "peek", 8 | // Auto fix 9 | "editor.codeActionsOnSave": { 10 | "source.fixAll.eslint": "explicit", 11 | "source.organizeImports": "never" 12 | }, 13 | // Silent the stylistic rules in you IDE, but still auto fix them 14 | "eslint.rules.customizations": [ 15 | { 16 | "rule": "style/*", 17 | "severity": "off" 18 | }, 19 | { 20 | "rule": "*-indent", 21 | "severity": "off" 22 | }, 23 | { 24 | "rule": "*-spacing", 25 | "severity": "off" 26 | }, 27 | { 28 | "rule": "*-spaces", 29 | "severity": "off" 30 | }, 31 | { 32 | "rule": "*-order", 33 | "severity": "off" 34 | }, 35 | { 36 | "rule": "*-dangle", 37 | "severity": "off" 38 | }, 39 | { 40 | "rule": "*-newline", 41 | "severity": "off" 42 | }, 43 | { 44 | "rule": "*quotes", 45 | "severity": "off" 46 | }, 47 | { 48 | "rule": "*semi", 49 | "severity": "off" 50 | } 51 | ], 52 | // Enable eslint for all supported languages 53 | "eslint.validate": [ 54 | "javascript", 55 | "javascriptreact", 56 | "typescript", 57 | "typescriptreact", 58 | "vue", 59 | "html", 60 | "markdown", 61 | "json", 62 | "jsonc", 63 | "yaml" 64 | ], 65 | "vue.codeActions.enabled": false 66 | } 67 | -------------------------------------------------------------------------------- /src/styles/variables.scss: -------------------------------------------------------------------------------- 1 | /* 2 | * uni-app uni.scss 内容,可直接修改 3 | * 参考 https://uniapp.dcloud.io/collocation/uni-scss 4 | */ 5 | 6 | /* 颜色变量 */ 7 | // 行为相关颜色 8 | $uni-color-primary: #007aff; 9 | $uni-color-success: #4cd964; 10 | $uni-color-warning: #f0ad4e; 11 | $uni-color-error: #dd524d; 12 | 13 | // 文字基本颜色 14 | $uni-text-color: #333; // 基本色 15 | $uni-text-color-inverse: #fff; // 反色 16 | $uni-text-color-grey: #999; // 辅助灰色,如加载更多的提示信息 17 | $uni-text-color-placeholder: #808080; 18 | $uni-text-color-disable: #c0c0c0; 19 | 20 | // 背景颜色 21 | $uni-bg-color: #fff; 22 | $uni-bg-color-grey: #f8f8f8; 23 | $uni-bg-color-hover: #f1f1f1; // 点击状态颜色 24 | $uni-bg-color-mask: rgb(0 0 0 / 40%); // 遮罩颜色 25 | // 边框颜色 26 | $uni-border-color: #c8c7cc; 27 | 28 | /* 尺寸变量 */ 29 | // 文字尺寸 30 | $uni-font-size-sm: 12px; 31 | $uni-font-size-base: 14px; 32 | $uni-font-size-lg: 16px; 33 | 34 | // 图片尺寸 35 | $uni-img-size-sm: 20px; 36 | $uni-img-size-base: 26px; 37 | $uni-img-size-lg: 40px; 38 | 39 | /* 边框圆角 */ 40 | $uni-border-radius-sm: 2px; 41 | $uni-border-radius-base: 3px; 42 | $uni-border-radius-lg: 6px; 43 | $uni-border-radius-circle: 50%; 44 | 45 | /** 间距变量 */ 46 | // 水平间距 47 | $uni-spacing-row-sm: 5px; 48 | $uni-spacing-row-base: 10px; 49 | $uni-spacing-row-lg: 15px; 50 | 51 | // 垂直间距 52 | $uni-spacing-col-sm: 4px; 53 | $uni-spacing-col-base: 8px; 54 | $uni-spacing-col-lg: 12px; 55 | 56 | /* 透明度 */ 57 | $uni-opacity-disabled: 0.3; // 组件禁用态的透明度 58 | 59 | /* 文章场景相关 */ 60 | $uni-color-title: #2c405a; // 文章标题颜色 61 | $uni-font-size-title: 20px; 62 | $uni-color-subtitle: #555; // 二级标题颜色 63 | $uni-font-size-subtitle: 18px; 64 | $uni-color-paragraph: #3f536e; // 文章段落颜色 65 | $uni-font-size-paragraph: 15px; 66 | 67 | @import 'nutui-uniapp/styles/variables'; 68 | -------------------------------------------------------------------------------- /src/manifest.json: -------------------------------------------------------------------------------- 1 | {"name":"uniapp-vite-template","appid":"","description":"","versionName":"1.0.0","versionCode":"100","transformPx":false,"app-plus":{"usingComponents":true,"nvueStyleCompiler":"uni-app","compilerVersion":3,"splashscreen":{"alwaysShowBeforeRender":true,"waiting":true,"autoclose":true,"delay":0},"modules":{"Canvas":"nvue canvas"},"distribute":{"android":{"permissions":["","","","","","","","","","","",""]},"ios":{},"sdkConfigs":{}}},"quickapp":{},"mp-weixin":{"appid":"","setting":{"urlCheck":false,"es6":true,"minified":true,"postcss":true,"ignoreDevUnusedFiles":false,"ignoreUploadUnusedFiles":false},"usingComponents":true,"lazyCodeLoading":"requiredComponents","darkmode":true,"themeLocation":"theme.json","libVersion":"3.4.3"},"mp-alipay":{"usingComponents":true},"mp-baidu":{"usingComponents":true},"mp-toutiao":{"usingComponents":true},"uniStatistics":{"enable":false},"vueVersion":"3","h5":{"darkmode":true,"themeLocation":"theme.json"}} -------------------------------------------------------------------------------- /src/service/types.ts: -------------------------------------------------------------------------------- 1 | import type { UnConfig, UnError, UnResponse } from '@uni-helper/uni-network' 2 | 3 | type IUnShowErrorType_ = 'toast' | 'modal' 4 | 5 | type IUnRequestData_ = Record 6 | 7 | interface IUnResponseData_ { 8 | code: number 9 | msg: string 10 | status: boolean 11 | data: T 12 | } 13 | 14 | interface IUnConfig_ extends UnConfig { 15 | showError?: boolean 16 | showErrorType?: IUnShowErrorType_ 17 | } 18 | interface IUnResponse_ extends UnResponse { } 19 | 20 | type IUnPromise_ = Promise> 21 | 22 | interface IUnError_ extends UnError { 23 | response?: IUnResponse_ 24 | } 25 | 26 | export type { 27 | IUnConfig_ as IUnConfig, 28 | IUnError_ as IUnError, 29 | IUnPromise_ as IUnPromise, 30 | IUnRequestData_ as IUnRequestData, 31 | IUnResponse_ as IUnResponse, 32 | IUnResponseData_ as IUnResponseData, 33 | IUnShowErrorType_ as IUnShowErrorType, 34 | } 35 | 36 | declare global { 37 | type IUnShowErrorType = IUnShowErrorType_ 38 | type IUnResponseData = IUnResponseData_ 39 | interface IUnRequestData extends IUnRequestData_ { } 40 | interface IUnConfig extends IUnConfig_, D> { } 41 | interface IUnResponse extends IUnResponse_, D> { } 42 | type IUnPromise = IUnPromise_, D> 43 | interface IUnError extends IUnError_, D> { } 44 | } 45 | -------------------------------------------------------------------------------- /src/uni.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * 这里是uni-app内置的常用样式变量 3 | * 4 | * uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量 5 | * 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App 6 | * 7 | */ 8 | 9 | /** 10 | * 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能 11 | * 12 | * 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件 13 | */ 14 | 15 | /* 颜色变量 */ 16 | 17 | /* uni.scss */ 18 | 19 | /* 行为相关颜色 */ 20 | $uni-color-primary: #007aff; 21 | $uni-color-success: #4cd964; 22 | $uni-color-warning: #f0ad4e; 23 | $uni-color-error: #dd524d; 24 | 25 | /* 文字基本颜色 */ 26 | $uni-text-color: #333; // 基本色 27 | $uni-text-color-inverse: #fff; // 反色 28 | $uni-text-color-grey: #999; // 辅助灰色,如加载更多的提示信息 29 | $uni-text-color-placeholder: #808080; 30 | $uni-text-color-disable: #c0c0c0; 31 | 32 | /* 背景颜色 */ 33 | $uni-bg-color: #fff; 34 | $uni-bg-color-grey: #f8f8f8; 35 | $uni-bg-color-hover: #f1f1f1; // 点击状态颜色 36 | $uni-bg-color-mask: rgb(0 0 0 / 40%); // 遮罩颜色 37 | 38 | /* 边框颜色 */ 39 | $uni-border-color: #c8c7cc; 40 | 41 | /* 尺寸变量 */ 42 | 43 | /* 文字尺寸 */ 44 | $uni-font-size-sm: 12px; 45 | $uni-font-size-base: 14px; 46 | $uni-font-size-lg: 16; 47 | 48 | /* 图片尺寸 */ 49 | $uni-img-size-sm: 20px; 50 | $uni-img-size-base: 26px; 51 | $uni-img-size-lg: 40px; 52 | 53 | /* Border Radius */ 54 | $uni-border-radius-sm: 2px; 55 | $uni-border-radius-base: 3px; 56 | $uni-border-radius-lg: 6px; 57 | $uni-border-radius-circle: 50%; 58 | 59 | /* 水平间距 */ 60 | $uni-spacing-row-sm: 5px; 61 | $uni-spacing-row-base: 10px; 62 | $uni-spacing-row-lg: 15px; 63 | 64 | /* 垂直间距 */ 65 | $uni-spacing-col-sm: 4px; 66 | $uni-spacing-col-base: 8px; 67 | $uni-spacing-col-lg: 12px; 68 | 69 | /* 透明度 */ 70 | $uni-opacity-disabled: 0.3; // 组件禁用态的透明度 71 | 72 | /* 文章场景相关 */ 73 | $uni-color-title: #2c405a; // 文章标题颜色 74 | $uni-font-size-title: 20px; 75 | $uni-color-subtitle: #555; // 二级标题颜色 76 | $uni-font-size-subtitle: 18px; 77 | $uni-color-paragraph: #3f536e; // 文章段落颜色 78 | $uni-font-size-paragraph: 15px; 79 | -------------------------------------------------------------------------------- /src/service/index.ts: -------------------------------------------------------------------------------- 1 | import type { VueQueryPluginOptions } from '@tanstack/vue-query' 2 | import { DefaultBaseUrl, DefaultHeaders } from '@/constants' 3 | import { useAuthStore } from '@/store' 4 | import { MutationCache, QueryCache, QueryClient } from '@tanstack/vue-query' 5 | import un from '@uni-helper/uni-network' 6 | import qs from 'qs' 7 | import { showNetworkError } from './helper' 8 | 9 | const instance = un.create({ 10 | baseUrl: DefaultBaseUrl, 11 | timeout: 30_000, 12 | paramsSerializer: (params: any) => { 13 | const query = qs.stringify( 14 | Object.fromEntries( 15 | Object.entries(params).filter( 16 | ([, v]) => !['undefined', 'null', undefined, null].includes((v as any)?.toString() ?? v), 17 | ), 18 | ), 19 | ) 20 | 21 | return query 22 | }, 23 | }) 24 | 25 | instance.interceptors.request.use((config) => { 26 | const authStore = useAuthStore() 27 | config.headers = { 28 | ...DefaultHeaders, 29 | 'token': authStore.token, 30 | 'X-Token': authStore.token, 31 | 'X-Access-Token': authStore.token, 32 | ...config.headers, 33 | } 34 | return config 35 | }) 36 | instance.interceptors.response.use((response) => { 37 | const data = response as IUnResponse 38 | 39 | // if (response.config?.showError ?? true) { 40 | // showNetworkError({ 41 | // response: response as unknown as IUnResponse, 42 | // error: data?.data as unknown as IUnError, 43 | // type: data.config?.showErrorType, 44 | // }) 45 | // } 46 | return data 47 | }) 48 | 49 | export { instance as unInstance } 50 | 51 | export const vueQueryClient = new QueryClient({ 52 | queryCache: new QueryCache({ 53 | onError: (error) => { 54 | if (un.isCancel(error)) 55 | return 56 | showNetworkError({ error: error as IUnError }) 57 | }, 58 | }), 59 | mutationCache: new MutationCache({ 60 | onError: (error) => { 61 | if (un.isCancel(error)) 62 | return 63 | showNetworkError({ error: error as IUnError }) 64 | }, 65 | }), 66 | }) 67 | 68 | export const vueQueryPluginOptions: VueQueryPluginOptions = { 69 | queryClient: vueQueryClient, 70 | } 71 | -------------------------------------------------------------------------------- /uno.config.ts: -------------------------------------------------------------------------------- 1 | import { 2 | type PresetOrFactory, 3 | type UserConfig, 4 | defineConfig, 5 | presetIcons, 6 | transformerDirectives, 7 | transformerVariantGroup, 8 | } from 'unocss' 9 | import presetRemToPx from '@unocss/preset-rem-to-px' 10 | import { isH5, isMp } from '@uni-helper/uni-env' 11 | import { presetUni } from '@uni-helper/unocss-preset-uni' 12 | 13 | const darkMode = isH5 ? 'class' : 'media' 14 | 15 | const config: UserConfig = defineConfig({ 16 | content: { 17 | pipeline: { 18 | exclude: [ 19 | 'node_modules', 20 | '.git', 21 | '.github', 22 | '.husky', 23 | '.vscode', 24 | 'build', 25 | 'dist', 26 | 'mock', 27 | 'public', 28 | 'types', 29 | './stats.html', 30 | ], 31 | }, 32 | }, 33 | shortcuts: [ 34 | ['btn', 'w-60 h-60 flex items-center justify-center rounded-full bg-teal-600 text-white cursor-pointer'], 35 | ['wh-full', 'w-full h-full'], 36 | ['f-c-c', 'flex justify-center items-center'], 37 | ['flex-col', 'flex flex-col'], 38 | ['absolute-lt', 'absolute left-0 top-0'], 39 | ['absolute-lb', 'absolute left-0 bottom-0'], 40 | ['absolute-rt', 'absolute right-0 top-0'], 41 | ['absolute-rb', 'absolute right-0 bottom-0'], 42 | ['absolute-center', 'absolute-lt f-c-c wh-full'], 43 | ['text-ellipsis', 'truncate'], 44 | [ 45 | 'icon-btn', 46 | 'inline-block cursor-pointer select-none opacity-75 transition duration-200 ease-in-out hover:opacity-100 hover:text-teal-600', 47 | ], 48 | ], 49 | presets: [ 50 | presetUni({ 51 | uno: { 52 | dark: darkMode, 53 | variablePrefix: 'li-', 54 | }, 55 | attributify: { 56 | ignoreAttributes: ['block', 'fixed'], 57 | }, 58 | remRpx: { 59 | baseFontSize: 2, 60 | mode: isMp ? 'rem2rpx' : 'rpx2rem', 61 | }, 62 | }) as PresetOrFactory, 63 | presetIcons({ 64 | scale: 1.2, 65 | warn: true, 66 | extraProperties: { 67 | 'display': 'inline-block', 68 | 'vertical-align': 'middle', 69 | }, 70 | }), 71 | // 保持h5和微信小程序转换比例一致 72 | presetRemToPx({ baseFontSize: 2 }), 73 | ], 74 | transformers: [ 75 | transformerDirectives(), 76 | transformerVariantGroup(), 77 | ], 78 | safelist: 'prose prose-sm m-auto text-left'.split(' '), 79 | theme: { 80 | preflightRoot: isMp ? ['page,::before,::after'] : undefined, 81 | }, 82 | }) 83 | 84 | export default config 85 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 🚀🚀🚀 一个Uniapp的起始模版,Vite,Vue3,TypeScript 2 | 3 |
4 | 5 |

6 | 预览 7 |

8 | 9 | Inspired by [Vitesse](https://github.com/antfu/vitesse) ❤ 10 | 11 | ### Features 12 | 13 | - ⚡️ [Vue3](https://vuejs.org/), [Vite 4](https://github.com/vitejs/vite), [pnpm](https://pnpm.io/), [ESBuild](https://github.com/evanw/esbuild) - 就是快! 14 | - 🗂 [基于文件的路由](https://github.com/uni-helper/vite-plugin-uni-pages) 15 | - 📦 [组件自动化加载](https://github.com/uni-helper/vite-plugin-uni-components) 16 | - 🎨 [UnoCSS](https://github.com/antfu/unocss) - 高性能且极具灵活性的即时原子化 CSS 引擎 17 | - 😃 [各种图标集为你所用](https://github.com/antfu/unocss/tree/main/packages/preset-icons) 18 | - 🔥 使用 [新的 `