├── .editorconfig ├── .eslintrc-auto-import.json ├── .gitignore ├── .npmrc ├── .vscode ├── extensions.json ├── settings.json └── tailwind.json ├── LICENSE ├── README.md ├── eslint.config.mjs ├── index.html ├── netlify.toml ├── package.json ├── platform.ts ├── pnpm-lock.yaml ├── postcss.config.ts ├── src ├── App.vue ├── auto-imports.d.ts ├── components │ └── WeappTailwindcss.vue ├── env.d.ts ├── main.ts ├── manifest.json ├── pages.json ├── pages │ └── index │ │ └── index.vue ├── static │ └── .gitkeep ├── stores │ └── counter.ts ├── theme.json └── uni.scss ├── stylelint.config.mjs ├── tailwind.config.ts ├── tsconfig.json └── vite.config.ts /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: https://EditorConfig.org 2 | 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | [*] 7 | indent_style = space 8 | indent_size = 2 9 | end_of_line = lf 10 | charset = utf-8 11 | trim_trailing_whitespace = false 12 | insert_final_newline = false -------------------------------------------------------------------------------- /.eslintrc-auto-import.json: -------------------------------------------------------------------------------- 1 | { 2 | "globals": { 3 | "Component": true, 4 | "ComponentPublicInstance": true, 5 | "ComputedRef": true, 6 | "DirectiveBinding": true, 7 | "EffectScope": true, 8 | "ExtractDefaultPropTypes": true, 9 | "ExtractPropTypes": true, 10 | "ExtractPublicPropTypes": true, 11 | "InjectionKey": true, 12 | "MaybeRef": true, 13 | "MaybeRefOrGetter": true, 14 | "PropType": true, 15 | "Ref": true, 16 | "ShallowRef": true, 17 | "Slot": true, 18 | "Slots": true, 19 | "VNode": true, 20 | "WritableComputedRef": true, 21 | "acceptHMRUpdate": true, 22 | "computed": true, 23 | "createApp": true, 24 | "createPinia": true, 25 | "customRef": true, 26 | "defineAsyncComponent": true, 27 | "defineComponent": true, 28 | "defineStore": true, 29 | "effectScope": true, 30 | "getActivePinia": true, 31 | "getCurrentInstance": true, 32 | "getCurrentScope": true, 33 | "getCurrentWatcher": true, 34 | "h": true, 35 | "inject": true, 36 | "isProxy": true, 37 | "isReactive": true, 38 | "isReadonly": true, 39 | "isRef": true, 40 | "isShallow": true, 41 | "mapActions": true, 42 | "mapGetters": true, 43 | "mapState": true, 44 | "mapStores": true, 45 | "mapWritableState": true, 46 | "markRaw": true, 47 | "nextTick": true, 48 | "onActivated": true, 49 | "onAddToFavorites": true, 50 | "onBackPress": true, 51 | "onBeforeMount": true, 52 | "onBeforeUnmount": true, 53 | "onBeforeUpdate": true, 54 | "onDeactivated": true, 55 | "onError": true, 56 | "onErrorCaptured": true, 57 | "onHide": true, 58 | "onLaunch": true, 59 | "onLoad": true, 60 | "onMounted": true, 61 | "onNavigationBarButtonTap": true, 62 | "onNavigationBarSearchInputChanged": true, 63 | "onNavigationBarSearchInputClicked": true, 64 | "onNavigationBarSearchInputConfirmed": true, 65 | "onNavigationBarSearchInputFocusChanged": true, 66 | "onPageNotFound": true, 67 | "onPageScroll": true, 68 | "onPullDownRefresh": true, 69 | "onReachBottom": true, 70 | "onReady": true, 71 | "onRenderTracked": true, 72 | "onRenderTriggered": true, 73 | "onResize": true, 74 | "onScopeDispose": true, 75 | "onServerPrefetch": true, 76 | "onShareAppMessage": true, 77 | "onShareTimeline": true, 78 | "onShow": true, 79 | "onTabItemTap": true, 80 | "onThemeChange": true, 81 | "onUnhandledRejection": true, 82 | "onUnload": true, 83 | "onUnmounted": true, 84 | "onUpdated": true, 85 | "onWatcherCleanup": true, 86 | "provide": true, 87 | "reactive": true, 88 | "readonly": true, 89 | "ref": true, 90 | "resolveComponent": true, 91 | "setActivePinia": true, 92 | "setMapStoreSuffix": true, 93 | "shallowReactive": true, 94 | "shallowReadonly": true, 95 | "shallowRef": true, 96 | "storeToRefs": true, 97 | "toRaw": true, 98 | "toRef": true, 99 | "toRefs": true, 100 | "toValue": true, 101 | "triggerRef": true, 102 | "unref": true, 103 | "useAttrs": true, 104 | "useCssModule": true, 105 | "useCssVars": true, 106 | "useId": true, 107 | "useModel": true, 108 | "useSlots": true, 109 | "useTemplateRef": true, 110 | "watch": true, 111 | "watchEffect": true, 112 | "watchPostEffect": true, 113 | "watchSyncEffect": true 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | unpackage/ 4 | dist/ 5 | 6 | # local env files 7 | .env.local 8 | .env.*.local 9 | 10 | # Log files 11 | npm-debug.log* 12 | yarn-debug.log* 13 | yarn-error.log* 14 | 15 | # Editor directories and files 16 | .project 17 | .idea 18 | *.suo 19 | *.ntvs* 20 | *.njsproj 21 | *.sln 22 | *.sw* 23 | # 要提交 .env 来确保 jit v2 的开发 watch mode 24 | !.env 25 | 26 | src/ignore 27 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | # 设置国内镜像地址 2 | # registry=http://registry.npmmirror.com/ 3 | registry=http://registry.npmjs.com/ 4 | # 这个是给 pnpm 用的 5 | shamefully-hoist=true 6 | 7 | ignore-engines=true 8 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "dbaeumer.vscode-eslint", 4 | "stylelint.vscode-stylelint", 5 | "bradlc.vscode-tailwindcss" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | // Disable the default formatter, use eslint instead 3 | "prettier.enable": false, 4 | "editor.formatOnSave": false, 5 | // Auto fix 6 | "editor.codeActionsOnSave": { 7 | "source.fixAll.eslint": "explicit", 8 | "source.organizeImports": "never" 9 | }, 10 | // https://github.com/tailwindlabs/tailwindcss/discussions/5258 11 | "css.customData": [ 12 | ".vscode/tailwind.json" 13 | ], 14 | "tailwindCSS.experimental.classRegex": [ 15 | // https://github.com/lukeed/clsx?tab=readme-ov-file#tailwind-support 16 | [ 17 | "clsx\\(([^)]*)\\)", 18 | "(?:'|\"|`)([^']*)(?:'|\"|`)" 19 | ], 20 | // https://cva.style/docs/getting-started/installation 21 | [ 22 | "cva\\(([^)]*)\\)", 23 | "[\"'`]([^\"'`]*).*?[\"'`]" 24 | ], 25 | [ 26 | "cx\\(([^)]*)\\)", 27 | "(?:'|\"|`)([^']*)(?:'|\"|`)" 28 | ] 29 | ], 30 | // Silent the stylistic rules in you IDE, but still auto fix them 31 | "eslint.rules.customizations": [ 32 | { 33 | "rule": "style/*", 34 | "severity": "off" 35 | }, 36 | { 37 | "rule": "format/*", 38 | "severity": "off" 39 | }, 40 | { 41 | "rule": "*-indent", 42 | "severity": "off" 43 | }, 44 | { 45 | "rule": "*-spacing", 46 | "severity": "off" 47 | }, 48 | { 49 | "rule": "*-spaces", 50 | "severity": "off" 51 | }, 52 | { 53 | "rule": "*-order", 54 | "severity": "off" 55 | }, 56 | { 57 | "rule": "*-dangle", 58 | "severity": "off" 59 | }, 60 | { 61 | "rule": "*-newline", 62 | "severity": "off" 63 | }, 64 | { 65 | "rule": "*quotes", 66 | "severity": "off" 67 | }, 68 | { 69 | "rule": "*semi", 70 | "severity": "off" 71 | } 72 | ], 73 | // Enable eslint for all supported languages 74 | "eslint.validate": [ 75 | "javascript", 76 | "javascriptreact", 77 | "typescript", 78 | "typescriptreact", 79 | "vue", 80 | "html", 81 | "markdown", 82 | "json", 83 | "jsonc", 84 | "yaml", 85 | "toml", 86 | "xml", 87 | "gql", 88 | "graphql", 89 | "astro", 90 | "css", 91 | "less", 92 | "scss", 93 | "pcss", 94 | "postcss" 95 | ], 96 | "css.validate": false, 97 | "less.validate": false, 98 | "scss.validate": false, 99 | "stylelint.validate": [ 100 | "vue", 101 | "css", 102 | "scss" 103 | ] 104 | } 105 | -------------------------------------------------------------------------------- /.vscode/tailwind.json: -------------------------------------------------------------------------------- 1 | // https://github.com/tailwindlabs/tailwindcss/discussions/5258 2 | { 3 | "version": 1.1, 4 | "atDirectives": [ 5 | { 6 | "name": "@tailwind", 7 | "description": "Use the `@tailwind` directive to insert Tailwind's `base`, `components`, `utilities` and `screens` styles into your CSS.", 8 | "references": [ 9 | { 10 | "name": "Tailwind Documentation", 11 | "url": "https://tailwindcss.com/docs/functions-and-directives#tailwind" 12 | } 13 | ] 14 | }, 15 | { 16 | "name": "@apply", 17 | "description": "Use the `@apply` directive to inline any existing utility classes into your own custom CSS. This is useful when you find a common utility pattern in your HTML that you’d like to extract to a new component.", 18 | "references": [ 19 | { 20 | "name": "Tailwind Documentation", 21 | "url": "https://tailwindcss.com/docs/functions-and-directives#apply" 22 | } 23 | ] 24 | }, 25 | { 26 | "name": "@responsive", 27 | "description": "You can generate responsive variants of your own classes by wrapping their definitions in the `@responsive` directive:\n```css\n@responsive {\n .alert {\n background-color: #E53E3E;\n }\n}\n```\n", 28 | "references": [ 29 | { 30 | "name": "Tailwind Documentation", 31 | "url": "https://tailwindcss.com/docs/functions-and-directives#responsive" 32 | } 33 | ] 34 | }, 35 | { 36 | "name": "@screen", 37 | "description": "The `@screen` directive allows you to create media queries that reference your breakpoints by **name** instead of duplicating their values in your own CSS:\n```css\n@screen sm {\n /* ... */\n}\n```\n…gets transformed into this:\n```css\n@media (min-width: 640px) {\n /* ... */\n}\n```\n", 38 | "references": [ 39 | { 40 | "name": "Tailwind Documentation", 41 | "url": "https://tailwindcss.com/docs/functions-and-directives#screen" 42 | } 43 | ] 44 | }, 45 | { 46 | "name": "@variants", 47 | "description": "Generate `hover`, `focus`, `active` and other **variants** of your own utilities by wrapping their definitions in the `@variants` directive:\n```css\n@variants hover, focus {\n .btn-brand {\n background-color: #3182CE;\n }\n}\n```\n", 48 | "references": [ 49 | { 50 | "name": "Tailwind Documentation", 51 | "url": "https://tailwindcss.com/docs/functions-and-directives#variants" 52 | } 53 | ] 54 | } 55 | ] 56 | } 57 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 ice breaker 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # uni-app-vite-vue3-tailwind-vscode-template 2 | 3 | 基于 `uni-app` 的 `vite` + `vue3` + `tailwindcss` 模板 4 | 5 | 假如你觉得好用,欢迎给我的 [`weapp-tailwindcss`](https://github.com/sonofmagic/weapp-tailwindcss) 点个 `Star` 吧。 6 | 7 | 官网地址: 8 | 9 | ## 特性 10 | 11 | - ⚡️ [Vue 3](https://github.com/vuejs/core), [Vite](https://github.com/vitejs/vite), [pnpm](https://pnpm.io/) - 快 & 稳定 12 | 13 | - 🎨 [TailwindCSS](https://tailwindcss.com/) - 世界上最流行,生态最好的原子化CSS框架 14 | 15 | - 😃 [集成 Iconify](https://github.com/egoist/tailwindcss-icons) - [icones.js.org](https://icones.js.org/) 中的所有图标都为你所用 16 | 17 | - 📥 [API 自动加载](https://github.com/antfu/unplugin-auto-import) - 直接使用 Composition API 无需引入 18 | 19 | - 🧬 [uni-app 条件编译样式](https://tw.icebreaker.top/docs/quick-start/uni-app-css-macro) - 帮助你在多端更灵活的使用 `TailwindCSS` 20 | 21 | - 🦾 [TypeScript](https://www.typescriptlang.org/) & [ESLint](https://eslint.org/) & [Stylelint](https://stylelint.io/) - 样式,类型,统一的校验与格式化规则,保证你的代码风格和质量 22 | 23 | ## 快速开始 24 | 25 | > [!IMPORTANT] 26 | > 请使用 Node >=22(LTS) 运行此项目! 详见 [issues/29](https://github.com/sonofmagic/uni-app-vite-vue3-tailwind-vscode-template/issues/29) 27 | > 28 | > 另外谨慎升级 `package.json` 中锁定的 `pinia`/`vue`/`@vue/*` 相关包的版本,新版本可能 `uni-app` 没有兼容,造成一些奇怪的 bug 29 | 30 | ### vscode 31 | 32 | 使用 `vscode` 的开发者,请先安装 [Tailwind CSS IntelliSense](https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss) 智能提示与感应插件 33 | 34 | 其他 IDE 请参考: 35 | 36 | ### 更换 Appid 37 | 38 | 把 `src/manifest.json` 中的 `appid`, 更换为你自己的 `appid`, 比如 `uni-app` / `mp-weixin` 平台。 39 | 40 | ## 升级依赖 41 | 42 | - `pnpm up:pkg` 升级除了 `uni-app` 相关的其他依赖 43 | - `pnpm up:uniapp` 升级 `uni-app` 相关的依赖 44 | 45 | 推荐先使用 `pnpm up:pkg` 升级, 再使用 `pnpm up:uniapp` 进行升级,因为 `pnpm up:uniapp` 很有可能会进行版本的降级已达到和 `uni-app` 版本匹配的效果 46 | 47 | ## 切换到国内镜像源 48 | 49 | 默认情况下,走的是官方 `npmjs` 源: `registry.npmjs.com` 50 | 51 | 假如你访问网速慢,要切换到淘宝镜像源,那就把目录下的 `.npmrc` 中的 `registry=http://registry.npmmirror.com/` **反注释** 52 | 53 | 然后再把 `registry=http://registry.npmjs.com/` 注释(前面加个 `#` 号即可),然后重新进行 `pnpm i` 安装包即可 54 | 55 | ## 包管理器 56 | 57 | 本项目默认使用 `pnpm@10` 进行管理,当然你也可以切换到其他包管理器,比如 `yarn`, `npm` 58 | 59 | 你只需要把 `pnpm-lock.yaml` 删掉,然后把 `package.json` 中的 `packageManager` 字段去除或者换成你具体的包管理器版本,然后重新安装即可 60 | 61 | ## eslint 代码校验 62 | 63 | 本项目集成的是我自己封装的 `@icebreakers/eslint-config` 规则,你不喜欢完全可以更换,卸载掉它然后自行配置 `eslint`,把它变成你想要的样子 64 | 65 | ### weapp-ide-cli 66 | 67 | 本项目已经集成 `weapp-ide-cli` 可以通过 `cli` 对 `ide` 进行额外操作 68 | 69 | - `pnpm open:dev` 打开微信开发者工具,引入 `dist/dev/mp-weixin` 70 | - `pnpm open:build` 打开微信开发者工具,引入 `dist/build/mp-weixin` 71 | 72 | [详细信息](https://www.npmjs.com/package/weapp-ide-cli) 73 | 74 | ## 其他模板 75 | 76 | 👉 [🔥 tarojs / 🔥 uni-app / 🔥 hbuilderx 等更多模板链接](https://tw.icebreaker.top/docs/community/templates) 77 | 78 | ## tailwindcss 生态 79 | 80 | 详见:https://github.com/aniftyco/awesome-tailwindcss 81 | 82 | 你可以在这里找到许多现成的UI,组件模板。 83 | 84 | ## 单位转换 85 | 86 | - `rem` -> `rpx` (默认开启, 见 `vite.config.ts` 中 `uvtw` 插件的 `rem2rpx` 选项) 87 | - `px` -> `rpx` (默认不开启,可在 `postcss.config.ts` 中引入 `postcss-pxtransform` 开启配置) 88 | 89 | ## Tips 90 | 91 | - 升级 `uni-app` 依赖的方式为 `npx @dcloudio/uvm` 后,选择对应的 `Package Manager` 即可。而升级其他包的方式,可以使用 `pnpm up -Li`,这个是 `pnpm` 自带的方式。 92 | - 使用 `vscode` 记得安装官方插件 `eslint`,`stylelint`,`tailwindcss`, 已在 `.vscode/extensions.json` 中设置推荐 93 | -------------------------------------------------------------------------------- /eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import { icebreaker } from '@icebreakers/eslint-config' 2 | 3 | export default icebreaker( 4 | { 5 | vue: true, 6 | tailwindcss: { 7 | tailwindConfig: './tailwind.config.ts', 8 | }, 9 | weapp: true, 10 | 11 | }, 12 | { 13 | // 规则可以在这里禁用 14 | rules: { 15 | 'better-tailwindcss/no-unregistered-classes': 'off', 16 | }, 17 | }, 18 | ) 19 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /netlify.toml: -------------------------------------------------------------------------------- 1 | # netlify 部署文件 2 | # 用于部署此项目的 h5 产物,可删除 3 | [build] 4 | publish = "dist/build/h5" 5 | command = "pnpm run build:h5" 6 | 7 | [build.environment] 8 | NODE_VERSION = "20" 9 | 10 | [[redirects]] 11 | from = "/*" 12 | to = "/index.html" 13 | status = 200 14 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "uni-app-vite-vue3-tailwind-vscode-template", 3 | "version": "0.0.0", 4 | "packageManager": "pnpm@10.18.3", 5 | "scripts": { 6 | "dev": "uni -p mp-weixin", 7 | "build": "npm run build:mp-weixin", 8 | "dev:app": "uni -p app", 9 | "dev:custom": "uni -p", 10 | "dev:h5": "uni", 11 | "dev:h5:ssr": "uni --ssr", 12 | "dev:mp-alipay": "uni -p mp-alipay", 13 | "dev:mp-baidu": "uni -p mp-baidu", 14 | "dev:mp-kuaishou": "uni -p mp-kuaishou", 15 | "dev:mp-lark": "uni -p mp-lark", 16 | "dev:mp-qq": "uni -p mp-qq", 17 | "dev:mp-toutiao": "uni -p mp-toutiao", 18 | "dev:mp-weixin": "uni -p mp-weixin", 19 | "dev:quickapp-webview": "uni -p quickapp-webview", 20 | "dev:quickapp-webview-huawei": "uni -p quickapp-webview-huawei", 21 | "dev:quickapp-webview-union": "uni -p quickapp-webview-union", 22 | "build:app": "uni build -p app", 23 | "build:custom": "uni build -p", 24 | "build:h5": "uni build", 25 | "build:h5:ssr": "uni build --ssr", 26 | "build:mp-alipay": "uni build -p mp-alipay", 27 | "build:mp-baidu": "uni build -p mp-baidu", 28 | "build:mp-kuaishou": "uni build -p mp-kuaishou", 29 | "build:mp-lark": "uni build -p mp-lark", 30 | "build:mp-qq": "uni build -p mp-qq", 31 | "build:mp-toutiao": "uni build -p mp-toutiao", 32 | "build:mp-weixin": "uni build -p mp-weixin", 33 | "build:quickapp-webview": "uni build -p quickapp-webview", 34 | "build:quickapp-webview-huawei": "uni build -p quickapp-webview-huawei", 35 | "build:quickapp-webview-union": "uni build -p quickapp-webview-union", 36 | "open:dev": "weapp open -p dist/dev/mp-weixin", 37 | "open:build": "weapp open -p dist/build/mp-weixin", 38 | "weapp:login": "weapp login", 39 | "upload:dev": "weapp upload -p dist/dev/mp-weixin -v 1.0.0 -d \"dev version\"", 40 | "upload:build": "weapp upload -p dist/build/mp-weixin -v 1.0.0 -d \"release version\"", 41 | "postinstall": "weapp-tw patch", 42 | "lint": "eslint .", 43 | "lint:fix": "eslint ./src --fix", 44 | "up:pkg": "pnpm up -rLi \"!@dcloudio/*\"", 45 | "up:uniapp": "pnpx @dcloudio/uvm@latest" 46 | }, 47 | "dependencies": { 48 | "@dcloudio/uni-app": "3.0.0-4070620250821001", 49 | "@dcloudio/uni-app-harmony": "3.0.0-4070620250821001", 50 | "@dcloudio/uni-app-plus": "3.0.0-4070620250821001", 51 | "@dcloudio/uni-components": "3.0.0-4070620250821001", 52 | "@dcloudio/uni-h5": "3.0.0-4070620250821001", 53 | "@dcloudio/uni-mp-alipay": "3.0.0-4070620250821001", 54 | "@dcloudio/uni-mp-baidu": "3.0.0-4070620250821001", 55 | "@dcloudio/uni-mp-harmony": "3.0.0-4070620250821001", 56 | "@dcloudio/uni-mp-jd": "3.0.0-4070620250821001", 57 | "@dcloudio/uni-mp-kuaishou": "3.0.0-4070620250821001", 58 | "@dcloudio/uni-mp-lark": "3.0.0-4070620250821001", 59 | "@dcloudio/uni-mp-qq": "3.0.0-4070620250821001", 60 | "@dcloudio/uni-mp-toutiao": "3.0.0-4070620250821001", 61 | "@dcloudio/uni-mp-weixin": "3.0.0-4070620250821001", 62 | "@dcloudio/uni-mp-xhs": "3.0.0-4070620250821001", 63 | "@dcloudio/uni-quickapp-webview": "3.0.0-4070620250821001", 64 | "@vue/shared": "3.4.21", 65 | "pinia": "2.2.4", 66 | "vue": "^3.4.21", 67 | "vue-i18n": "^9.1.9" 68 | }, 69 | "devDependencies": { 70 | "@dcloudio/types": "^3.4.8", 71 | "@dcloudio/uni-automator": "3.0.0-4070620250821001", 72 | "@dcloudio/uni-cli-shared": "3.0.0-4070620250821001", 73 | "@dcloudio/uni-stacktracey": "3.0.0-4070620250821001", 74 | "@dcloudio/vite-plugin-uni": "3.0.0-4070620250821001", 75 | "@egoist/tailwindcss-icons": "^1.9.0", 76 | "@icebreakers/eslint-config": "^1.5.2", 77 | "@icebreakers/stylelint-config": "^1.2.1", 78 | "@iconify-json/mdi": "^1.2.3", 79 | "@iconify-json/svg-spinners": "^1.2.4", 80 | "@types/node": "^24.7.2", 81 | "@vue/runtime-core": "^3.4.21", 82 | "autoprefixer": "^10.4.21", 83 | "eslint": "^9.37.0", 84 | "postcss": "^8.5.6", 85 | "sass": "^1.93.2", 86 | "tailwindcss": "^3.4.18", 87 | "typescript": "^5.9.3", 88 | "unplugin-auto-import": "^20.2.0", 89 | "vite": "5.2.8", 90 | "weapp-ide-cli": "^4.0.0", 91 | "weapp-tailwindcss": "^4.5.1" 92 | }, 93 | "pnpm": { 94 | "onlyBuiltDependencies": [ 95 | "vue-demi", 96 | "weapp-tailwindcss" 97 | ] 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /platform.ts: -------------------------------------------------------------------------------- 1 | import process from 'node:process' 2 | 3 | const isH5 = process.env.UNI_PLATFORM === 'h5' 4 | const isApp = process.env.UNI_PLATFORM === 'app' 5 | const WeappTailwindcssDisabled = isH5 || isApp 6 | const isMp = !isH5 && !isApp 7 | 8 | export { 9 | isApp, 10 | isH5, 11 | isMp, 12 | WeappTailwindcssDisabled, 13 | } 14 | -------------------------------------------------------------------------------- /postcss.config.ts: -------------------------------------------------------------------------------- 1 | import type { AcceptedPlugin } from 'postcss' 2 | import autoprefixer from 'autoprefixer' 3 | import tailwindcss from 'tailwindcss' 4 | import cssMacro from 'weapp-tailwindcss/css-macro/postcss' 5 | 6 | const plugins: AcceptedPlugin[] = [tailwindcss(), autoprefixer()] 7 | 8 | // 可以使用 postcss-pxtransform 来进行 px 转 rpx 的功能 9 | // 详见: https://tw.icebreaker.top/docs/quick-start/css-unit-transform#px-%E8%BD%AC-rpx 10 | 11 | plugins.push(cssMacro) 12 | 13 | export default plugins 14 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 37 | -------------------------------------------------------------------------------- /src/auto-imports.d.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | /* prettier-ignore */ 3 | // @ts-nocheck 4 | // noinspection JSUnusedGlobalSymbols 5 | // Generated by unplugin-auto-import 6 | // biome-ignore lint: disable 7 | export {} 8 | declare global { 9 | const EffectScope: typeof import('vue')['EffectScope'] 10 | const acceptHMRUpdate: typeof import('pinia')['acceptHMRUpdate'] 11 | const computed: typeof import('vue')['computed'] 12 | const createApp: typeof import('vue')['createApp'] 13 | const createPinia: typeof import('pinia')['createPinia'] 14 | const customRef: typeof import('vue')['customRef'] 15 | const defineAsyncComponent: typeof import('vue')['defineAsyncComponent'] 16 | const defineComponent: typeof import('vue')['defineComponent'] 17 | const defineStore: typeof import('pinia')['defineStore'] 18 | const effectScope: typeof import('vue')['effectScope'] 19 | const getActivePinia: typeof import('pinia')['getActivePinia'] 20 | const getCurrentInstance: typeof import('vue')['getCurrentInstance'] 21 | const getCurrentScope: typeof import('vue')['getCurrentScope'] 22 | const getCurrentWatcher: typeof import('vue')['getCurrentWatcher'] 23 | const h: typeof import('vue')['h'] 24 | const inject: typeof import('vue')['inject'] 25 | const isProxy: typeof import('vue')['isProxy'] 26 | const isReactive: typeof import('vue')['isReactive'] 27 | const isReadonly: typeof import('vue')['isReadonly'] 28 | const isRef: typeof import('vue')['isRef'] 29 | const isShallow: typeof import('vue')['isShallow'] 30 | const mapActions: typeof import('pinia')['mapActions'] 31 | const mapGetters: typeof import('pinia')['mapGetters'] 32 | const mapState: typeof import('pinia')['mapState'] 33 | const mapStores: typeof import('pinia')['mapStores'] 34 | const mapWritableState: typeof import('pinia')['mapWritableState'] 35 | const markRaw: typeof import('vue')['markRaw'] 36 | const nextTick: typeof import('vue')['nextTick'] 37 | const onActivated: typeof import('vue')['onActivated'] 38 | const onAddToFavorites: typeof import('@dcloudio/uni-app')['onAddToFavorites'] 39 | const onBackPress: typeof import('@dcloudio/uni-app')['onBackPress'] 40 | const onBeforeMount: typeof import('vue')['onBeforeMount'] 41 | const onBeforeUnmount: typeof import('vue')['onBeforeUnmount'] 42 | const onBeforeUpdate: typeof import('vue')['onBeforeUpdate'] 43 | const onDeactivated: typeof import('vue')['onDeactivated'] 44 | const onError: typeof import('@dcloudio/uni-app')['onError'] 45 | const onErrorCaptured: typeof import('vue')['onErrorCaptured'] 46 | const onHide: typeof import('@dcloudio/uni-app')['onHide'] 47 | const onLaunch: typeof import('@dcloudio/uni-app')['onLaunch'] 48 | const onLoad: typeof import('@dcloudio/uni-app')['onLoad'] 49 | const onMounted: typeof import('vue')['onMounted'] 50 | const onNavigationBarButtonTap: typeof import('@dcloudio/uni-app')['onNavigationBarButtonTap'] 51 | const onNavigationBarSearchInputChanged: typeof import('@dcloudio/uni-app')['onNavigationBarSearchInputChanged'] 52 | const onNavigationBarSearchInputClicked: typeof import('@dcloudio/uni-app')['onNavigationBarSearchInputClicked'] 53 | const onNavigationBarSearchInputConfirmed: typeof import('@dcloudio/uni-app')['onNavigationBarSearchInputConfirmed'] 54 | const onNavigationBarSearchInputFocusChanged: typeof import('@dcloudio/uni-app')['onNavigationBarSearchInputFocusChanged'] 55 | const onPageNotFound: typeof import('@dcloudio/uni-app')['onPageNotFound'] 56 | const onPageScroll: typeof import('@dcloudio/uni-app')['onPageScroll'] 57 | const onPullDownRefresh: typeof import('@dcloudio/uni-app')['onPullDownRefresh'] 58 | const onReachBottom: typeof import('@dcloudio/uni-app')['onReachBottom'] 59 | const onReady: typeof import('@dcloudio/uni-app')['onReady'] 60 | const onRenderTracked: typeof import('vue')['onRenderTracked'] 61 | const onRenderTriggered: typeof import('vue')['onRenderTriggered'] 62 | const onResize: typeof import('@dcloudio/uni-app')['onResize'] 63 | const onScopeDispose: typeof import('vue')['onScopeDispose'] 64 | const onServerPrefetch: typeof import('vue')['onServerPrefetch'] 65 | const onShareAppMessage: typeof import('@dcloudio/uni-app')['onShareAppMessage'] 66 | const onShareTimeline: typeof import('@dcloudio/uni-app')['onShareTimeline'] 67 | const onShow: typeof import('@dcloudio/uni-app')['onShow'] 68 | const onTabItemTap: typeof import('@dcloudio/uni-app')['onTabItemTap'] 69 | const onThemeChange: typeof import('@dcloudio/uni-app')['onThemeChange'] 70 | const onUnhandledRejection: typeof import('@dcloudio/uni-app')['onUnhandledRejection'] 71 | const onUnload: typeof import('@dcloudio/uni-app')['onUnload'] 72 | const onUnmounted: typeof import('vue')['onUnmounted'] 73 | const onUpdated: typeof import('vue')['onUpdated'] 74 | const onWatcherCleanup: typeof import('vue')['onWatcherCleanup'] 75 | const provide: typeof import('vue')['provide'] 76 | const reactive: typeof import('vue')['reactive'] 77 | const readonly: typeof import('vue')['readonly'] 78 | const ref: typeof import('vue')['ref'] 79 | const resolveComponent: typeof import('vue')['resolveComponent'] 80 | const setActivePinia: typeof import('pinia')['setActivePinia'] 81 | const setMapStoreSuffix: typeof import('pinia')['setMapStoreSuffix'] 82 | const shallowReactive: typeof import('vue')['shallowReactive'] 83 | const shallowReadonly: typeof import('vue')['shallowReadonly'] 84 | const shallowRef: typeof import('vue')['shallowRef'] 85 | const storeToRefs: typeof import('pinia')['storeToRefs'] 86 | const toRaw: typeof import('vue')['toRaw'] 87 | const toRef: typeof import('vue')['toRef'] 88 | const toRefs: typeof import('vue')['toRefs'] 89 | const toValue: typeof import('vue')['toValue'] 90 | const triggerRef: typeof import('vue')['triggerRef'] 91 | const unref: typeof import('vue')['unref'] 92 | const useAttrs: typeof import('vue')['useAttrs'] 93 | const useCssModule: typeof import('vue')['useCssModule'] 94 | const useCssVars: typeof import('vue')['useCssVars'] 95 | const useId: typeof import('vue')['useId'] 96 | const useModel: typeof import('vue')['useModel'] 97 | const useSlots: typeof import('vue')['useSlots'] 98 | const useTemplateRef: typeof import('vue')['useTemplateRef'] 99 | const watch: typeof import('vue')['watch'] 100 | const watchEffect: typeof import('vue')['watchEffect'] 101 | const watchPostEffect: typeof import('vue')['watchPostEffect'] 102 | const watchSyncEffect: typeof import('vue')['watchSyncEffect'] 103 | } 104 | // for type re-export 105 | declare global { 106 | // @ts-ignore 107 | export type { Component, Slot, Slots, ComponentPublicInstance, ComputedRef, DirectiveBinding, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, ShallowRef, MaybeRef, MaybeRefOrGetter, VNode, WritableComputedRef } from 'vue' 108 | import('vue') 109 | } 110 | -------------------------------------------------------------------------------- /src/components/WeappTailwindcss.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 60 | -------------------------------------------------------------------------------- /src/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | declare module '*.vue' { 4 | import type { DefineComponent } from 'vue' 5 | 6 | const component: DefineComponent 7 | export default component 8 | } 9 | -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | import * as Pinia from 'pinia' 2 | import { createSSRApp } from 'vue' 3 | import App from './App.vue' 4 | 5 | export function createApp() { 6 | const app = createSSRApp(App) 7 | app.use(Pinia.createPinia()) 8 | return { 9 | app, 10 | Pinia, 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "uni-app-vue3-vite", 3 | "appid": "", 4 | "description": "", 5 | "versionName": "1.0.0", 6 | "versionCode": "100", 7 | "transformPx": false, 8 | /* 5+App特有相关 */ 9 | "app-plus": { 10 | "usingComponents": true, 11 | "nvueStyleCompiler": "uni-app", 12 | "compilerVersion": 3, 13 | "splashscreen": { 14 | "alwaysShowBeforeRender": true, 15 | "waiting": true, 16 | "autoclose": true, 17 | "delay": 0 18 | }, 19 | /* 模块配置 */ 20 | "modules": {}, 21 | /* 应用发布信息 */ 22 | "distribute": { 23 | /* android打包配置 */ 24 | "android": { 25 | "permissions": [ 26 | "", 27 | "", 28 | "", 29 | "", 30 | "", 31 | "", 32 | "", 33 | "", 34 | "", 35 | "", 36 | "", 37 | "", 38 | "", 39 | "", 40 | "" 41 | ] 42 | }, 43 | /* ios打包配置 */ 44 | "ios": {}, 45 | /* SDK配置 */ 46 | "sdkConfigs": {} 47 | } 48 | }, 49 | /* 快应用特有相关 */ 50 | "quickapp": {}, 51 | /* 小程序特有相关 */ 52 | "mp-weixin": { 53 | "appid": "wxb3d842a4a7e3440d", 54 | "setting": { 55 | "urlCheck": false 56 | }, 57 | "usingComponents": true, 58 | "lazyCodeLoading": "requiredComponents", 59 | "darkmode": true 60 | }, 61 | "mp-alipay": { 62 | "usingComponents": true 63 | }, 64 | "mp-baidu": { 65 | "usingComponents": true 66 | }, 67 | "mp-toutiao": { 68 | "usingComponents": true 69 | }, 70 | "uniStatistics": { 71 | "enable": false 72 | }, 73 | "vueVersion": "3" 74 | } 75 | -------------------------------------------------------------------------------- /src/pages.json: -------------------------------------------------------------------------------- 1 | { 2 | "pages": [ // pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages 3 | { 4 | "path": "pages/index/index", 5 | "style": { 6 | "navigationBarTitleText": "weapp-tailwindcss" 7 | } 8 | } 9 | ], 10 | "globalStyle": { 11 | "navigationBarTextStyle": "black", 12 | "navigationBarTitleText": "weapp-tailwindcss", 13 | "navigationBarBackgroundColor": "#F8F8F8", 14 | "backgroundColor": "#F8F8F8" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/pages/index/index.vue: -------------------------------------------------------------------------------- 1 | 61 | 62 | 198 | 199 | 219 | -------------------------------------------------------------------------------- /src/static/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sonofmagic/uni-app-vite-vue3-tailwind-vscode-template/cc8a114a3f5ece056aaa1a620678c40facefe080/src/static/.gitkeep -------------------------------------------------------------------------------- /src/stores/counter.ts: -------------------------------------------------------------------------------- 1 | import { defineStore } from 'pinia' 2 | import { ref } from 'vue' 3 | 4 | export const useCounterStore = defineStore('counter', () => { 5 | const count = ref(0) 6 | function increment() { 7 | count.value++ 8 | } 9 | 10 | return { count, increment } 11 | }) 12 | -------------------------------------------------------------------------------- /src/theme.json: -------------------------------------------------------------------------------- 1 | { 2 | "light": { 3 | "navBgColor": "#f6f6f6", 4 | "navTxtStyle": "black" 5 | }, 6 | "dark": { 7 | "navBgColor": "#191919", 8 | "navTxtStyle": "white" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/uni.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sonofmagic/uni-app-vite-vue3-tailwind-vscode-template/cc8a114a3f5ece056aaa1a620678c40facefe080/src/uni.scss -------------------------------------------------------------------------------- /stylelint.config.mjs: -------------------------------------------------------------------------------- 1 | import { icebreaker } from '@icebreakers/stylelint-config' 2 | 3 | export default icebreaker() 4 | -------------------------------------------------------------------------------- /tailwind.config.ts: -------------------------------------------------------------------------------- 1 | import type { Config } from 'tailwindcss' 2 | import { getIconCollections, iconsPlugin } from '@egoist/tailwindcss-icons' 3 | import cssMacro from 'weapp-tailwindcss/css-macro' 4 | import { isMp } from './platform' 5 | 6 | export default { 7 | content: ['./index.html', './src/**/*.{html,js,ts,jsx,tsx,vue}'], 8 | theme: { 9 | extend: { 10 | // colors: { 11 | // // 你可以在这里进行颜色的扩展 12 | // primary: { 13 | // 'DEFAULT': 'var(--color-primary, #0089FF)', 14 | // 'light-3': 'var(--color-primary-light-3, rgb(85, 199, 255))', 15 | // 'light-5': 'var(--color-primary-light-5, rgb(130, 217, 255))', 16 | // 'light-7': 'var(--color-primary-light-7, rgb(175, 235, 255))', 17 | // 'light-9': 'var(--color-primary-light-9, rgb(219, 252, 255))', 18 | // 'dark-2': 'var(--color-primary-dark-2, rgb(0, 135, 204))', 19 | // }, 20 | // }, 21 | }, 22 | }, 23 | // https://tw.icebreaker.top/docs/quick-start/uni-app-css-macro 24 | plugins: [ 25 | cssMacro({ 26 | variantsMap: { 27 | 'wx': 'MP-WEIXIN', 28 | '-wx': { 29 | value: 'MP-WEIXIN', 30 | negative: true, 31 | }, 32 | // 定义多个条件判断 33 | // mv: { 34 | // value: 'H5 || MP-WEIXIN' 35 | // }, 36 | // '-mv': { 37 | // value: 'H5 || MP-WEIXIN', 38 | // negative: true 39 | // } 40 | }, 41 | }), 42 | iconsPlugin({ 43 | // 在这里可以选择你要使用的 icon, 更多详见: 44 | // https://icon-sets.iconify.design/ 45 | collections: getIconCollections(['svg-spinners', 'mdi']), 46 | }), 47 | ], 48 | corePlugins: { 49 | // 小程序去使用 h5 的 preflight 和响应式 container 没有意义 50 | preflight: !isMp, 51 | container: !isMp, 52 | }, 53 | } 54 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "esnext", 4 | "jsx": "preserve", 5 | "lib": [ 6 | "esnext", 7 | "dom" 8 | ], 9 | "useDefineForClassFields": true, 10 | "baseUrl": ".", 11 | "module": "esnext", 12 | "moduleResolution": "node", 13 | "paths": { 14 | "@/*": [ 15 | "src/*" 16 | ] 17 | }, 18 | "resolveJsonModule": true, 19 | "types": [ 20 | "@dcloudio/types" 21 | ], 22 | "allowJs": true, 23 | "strict": true, 24 | "sourceMap": true, 25 | "esModuleInterop": true 26 | }, 27 | "include": [ 28 | "src/**/*.ts", 29 | "src/**/*.d.ts", 30 | "src/**/*.tsx", 31 | "src/**/*.vue" 32 | ] 33 | } 34 | -------------------------------------------------------------------------------- /vite.config.ts: -------------------------------------------------------------------------------- 1 | import uni from '@dcloudio/vite-plugin-uni' 2 | import { defineConfig } from 'vite' 3 | import { UnifiedViteWeappTailwindcssPlugin } from 'weapp-tailwindcss/vite' 4 | import { WeappTailwindcssDisabled } from './platform' 5 | import postcssPlugins from './postcss.config' 6 | 7 | // https://vitejs.dev/config/ 8 | export default defineConfig(async () => { 9 | // 新版本的 unplugin-auto-import 改成了只有 esm 格式的产物,而 uni-app 目前必须 cjs 格式 10 | // 所以需要改成动态 import 的写法来进行引入 11 | // 详见 https://github.com/sonofmagic/uni-app-vite-vue3-tailwind-vscode-template/issues/29 12 | const { default: AutoImport } = await import('unplugin-auto-import/vite') 13 | return { 14 | // uvtw 一定要放在 uni 后面 15 | plugins: [ 16 | uni(), 17 | UnifiedViteWeappTailwindcssPlugin({ 18 | rem2rpx: true, 19 | disabled: WeappTailwindcssDisabled, 20 | }), 21 | AutoImport({ 22 | imports: ['vue', 'uni-app', 'pinia'], 23 | dts: './src/auto-imports.d.ts', 24 | eslintrc: { 25 | enabled: true, 26 | }, 27 | }), 28 | ], 29 | // 内联 postcss 注册 tailwindcss 30 | css: { 31 | postcss: { 32 | plugins: postcssPlugins, 33 | }, 34 | // https://vitejs.dev/config/shared-options.html#css-preprocessoroptions 35 | preprocessorOptions: { 36 | scss: { 37 | silenceDeprecations: ['legacy-js-api'], 38 | }, 39 | }, 40 | }, 41 | } 42 | }) 43 | --------------------------------------------------------------------------------