Commit b38712f3 by 吴泽禄

Initial commit

parents
module.exports = {
extends: ['@commitlint/config-conventional'],
};
root = true
[*]
charset = utf-8
end_of_line = lf
indent_size = 2
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
[*.md]
trim_trailing_whitespace = false
module.exports = {
extends: [
require.resolve('@modyqyw/fabric/eslint/vanilla'),
require.resolve('@modyqyw/fabric/eslint/typescript'),
require.resolve('@modyqyw/fabric/eslint/vue'),
require.resolve('@modyqyw/fabric/eslint/miniprogram'),
],
};
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
pnpm-debug.log*
run
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules
jspm_packages
# Snowpack dependency directory (https://snowpack.dev/)
web_modules
# Temp directory
.temp
.tmp
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Microbundle cache
.rpt2_cache
.rts2_cache_cjs
.rts2_cache_es
.rts2_cache_umd
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
.env.test
.env.*.test
.env.local
.env.*.local
*.local
# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache
# Electron
dist-electron
dist_electron
# Tauri
dist-tauri
dist_tauri
# Cordova
dist-cordova
dist_cordova
# Capacitor
dist-capacitor
dist_capacitor
# Next.js build output
.next
out
# Umi.js build output
.umi
.umi-production
.umi-test
# Nuxt.js build / generate output
.nuxt
dist
# Rax.js build
.rax
# Vuepress build output
.vuepress/dist
# SSR
dist-ssr
dist_ssr
# SSG
dist-ssg
dist_ssg
# Serverless
.serverless
.dynamodb
.s3
.buckets
.seeds
# FuseBox cache
.fusebox
# TernJS port file
.tern-port
# Cypress
/cypress/videos/
/cypress/screenshots/
# Editor
.vscode-test
.vscode/**
!.vscode/extensions.json
!.vscode/settings.json
*.vsix
.idea
.hbuilder
.hbuilderx
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
# yarn v2
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*
# Apple
.DS_Store
*.p12
*.mobileprovision
# Android
*.keystore
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npx --no-install commitlint --edit $1
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npx --no-install lint-staged
module.exports = {
'*.md': 'markdownlint --fix',
'*.{css,less,scss,sass,vue,svelte}': 'stylelint --fix',
'*.{js,cjs,mjs,jsx,ts,cts,mts,tsx,vue,svelte,yaml,yml,json,jsonc,json5}': 'eslint --fix',
};
{
"MD003": false,
"MD013": false,
"MD022": false,
"MD024": false,
"MD025": false,
"MD033": false,
"MD050": false
}
shamefully-hoist=true
module.exports = {
...require('@modyqyw/fabric/prettier'),
};
module.exports = {
git: {
commitMessage: 'chore(release): v${version}',
tagName: 'v${version}',
},
npm: {
publish: false,
},
github: {
release: false,
},
gitlab: {
release: false,
},
hooks: {
'before:init': 'npm install --legacy-peer-deps && npm run lint',
'after:bump': 'esmo ./scripts/update-manifest.mjs',
},
};
module.exports = {
extends: [
'@modyqyw/fabric/stylelint/css',
'@modyqyw/fabric/stylelint/scss',
'@modyqyw/fabric/stylelint/vue',
'@modyqyw/fabric/stylelint/miniprogram',
],
};
{
"recommendations": [
"russell.any-rule",
"streetsidesoftware.code-spell-checker",
"adam-bender.commit-message-editor",
"mikestead.dotenv",
"editorconfig.editorconfig",
"dbaeumer.vscode-eslint",
"mhutchie.git-graph",
"donjayamanne.githistory",
"eamodio.gitlens",
"lokalise.i18n-ally",
"kisstkondoros.vscode-gutter-preview",
"yzhang.markdown-all-in-one",
"shd101wyy.markdown-preview-enhanced",
"davidanson.vscode-markdownlint",
"esbenp.prettier-vscode",
"iceworks-team.iceworks-style-helper",
"chrmarti.regex",
"syler.sass-indented",
"stylelint.vscode-stylelint",
"jock.svg",
"bradlc.vscode-tailwindcss",
"gruntfuggly.todo-tree",
"johnsoncodehk.vscode-typescript-vue-plugin",
"johnsoncodehk.volar",
"redhat.vscode-yaml"
]
}
{
"cSpell.language": "en,en-US",
"cSpell.enabledLanguageIds": [
"css",
"html",
"javascript",
"javascriptreact",
"json",
"jsonc",
"json5",
"less",
"markdown",
"plaintext",
"sass",
"scss",
"text",
"typescript",
"typescriptreact",
"vue",
"yaml",
"yml"
],
"css.validate": false,
"editor.bracketPairColorization.enabled": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
"editor.guides.bracketPairs": true,
"editor.inlineSuggest.enabled": true,
"editor.tabSize": 2,
"editor.wordWrap": "on",
"eslint.validate": ["javascript", "javascriptreact", "typescript", "typescriptreact", "vue"],
"eslint.alwaysShowStatus": true,
"files.eol": "\n",
"files.associations": {
"*.wxml": "html",
"*.wxs": "javascript",
"*.wxss": "css",
"*.axml": "html",
"*.sjs": "javascript",
"*.acss": "css",
"*.swan": "html",
"*.ttml": "html",
"*.ttss": "css",
"*.jxml": "html",
"*.jxss": "css",
"*.json": "jsonc",
"*.json5": "jsonc",
"*.nvue": "vue",
"*.ux": "vue"
},
"git.autofetch": true,
"js/ts.implicitProjectConfig.experimentalDecorators": true,
"javascript.updateImportsOnFileMove.enabled": "always",
"less.validate": false,
"scss.validate": false,
"stylelint.snippet": ["css", "less", "sass", "scss", "vue"],
"stylelint.validate": ["css", "less", "sass", "scss", "vue"],
"todo-tree.highlights.customHighlight": {
"FIX": {
"background": "#d32029",
"foreground": "#fff",
"icon": "bug",
"iconColour": "#d32029"
},
"PERF": {
"background": "#2b4acb",
"foreground": "#fff",
"icon": "flame",
"iconColour": "#2b4acb"
},
"TODO": {
"background": "#d89614",
"foreground": "#fff",
"icon": "alert",
"iconColour": "#d89614"
},
"[ ]": {
"icon": "circle"
},
"[x]": {
"icon": "check"
}
},
"todo-tree.highlights.defaultHighlight": {
"gutterIcon": true
},
"todo-tree.general.tagGroups": {
"FIX": ["FIXME", "FIXIT", "FIX", "BUG"]
},
"todo-tree.general.tags": ["FIX", "FIXME", "FITIT", "BUG", "PERF", "TODO", "[ ]", "[x]"],
"todo-tree.regex.regex": "(//|#|<!--|;|/\\*|^|^\\s*(-|\\d+.))\\s*($TAGS)",
"typescript.updateImportsOnFileMove.enabled": "always",
"[javascript]": {
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
}
},
"[javascriptreact]": {
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
}
},
"[typescript]": {
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
}
},
"[typescriptreact]": {
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
}
},
"[css]": {
"editor.codeActionsOnSave": {
"source.fixAll.stylelint": true
}
},
"[less]": {
"editor.codeActionsOnSave": {
"source.fixAll.stylelint": true
}
},
"[sass]": {
"editor.codeActionsOnSave": {
"source.fixAll.stylelint": true
}
},
"[scss]": {
"editor.codeActionsOnSave": {
"source.fixAll.stylelint": true
}
},
"[vue]": {
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true,
"source.fixAll.stylelint": true
}
},
"[markdown]": {
"editor.codeActionsOnSave": {
"source.fixAll.markdownlint": true
}
}
}
# boilerplate-uni-app-vue3
**已经迁移到 [MillCloud/presets](https://github.com/MillCloud/presets)。**
## 简介
`boilerplate-uni-app-vue3` 是一个面向中国用户的简单 `uni-app (vue3)` 模板,目标是帮助你快速开发小程序/移动端应用。当然,也希望能引导你更进一步地了解 `uni-app (vue3)` 生态。
如果你想要快速开发桌面端网页/移动端网页,请考虑使用 [boilerplate-vue3](https://github.com/MillCloud/boilerplate-vue3)
`uni-app` 并不是一个尽善尽美的方案,在很多细节上还有待提高。如果你只是想要开发移动端应用,也可以考虑使用 [boilerplate-vue3](https://github.com/MillCloud/boilerplate-vue3),加入 [cordova](https://cordova.apache.org/)[native-script](https://nativescript.org/)[ionic](https://ionicframework.com/)[capacitor](https://capacitorjs.com/)
该模板只支持 vue 3。vue 2 支持请查看 [boilerplate-uni-app-vue2](https://github.com/MillCloud/boilerplate-uni-app-vue2)
### 主要依赖
- [vue3](https://v3.cn.vuejs.org/)
- [vite](https://cn.vitejs.dev/)
- [pinia](https://pinia.esm.dev/)
- [vue-use](https://vueuse.org)
- [typescript](https://www.typescriptlang.org/zh/)
- [vue-query](https://vue-query.vercel.app/)
- [statuses](https://github.com/jshttp/statuses)
- [tailwindcss](https://tailwindcss.com/)
- [@dcloudio/uni-ui](https://github.com/dcloudio/uni-ui)
- [thor-ui](https://thorui.cn/)
- [lodash](https://lodash.com/)
- [ramda](https://ramdajs.com/)
- [dayjs](https://dayjs.gitee.io/zh-CN/)
- [sass](https://sass-lang.com/)
- [@modyqyw/fabric](https://github.com/ModyQyW/fabric)
- [npm-check-updates](https://github.com/raineorshine/npm-check-updates)
请先阅读上面的文档,并确保对 `node``npm`[基本了解](http://nodejs.cn/learn)
## 起步
这部分说明将让你得到能在本地运行的项目副本以开始开发。有关如何部署项目,请阅读 [部署部分](#部署)
### 准备
你可能需要使用梯子或手机 WiFi 完成准备步骤。
对于 macOS 用户,请按照以下指引操作。
```sh
# 安装 nvm
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
# 设置镜像,加快下载速度
export NVM_NODEJS_ORG_MIRROR=https://npmmirror.com/mirrors/node
# 安装 node@lts
nvm install --lts
# 使用 node@lts
nvm use --lts
# 设置默认版本
nvm alias default node
# 更新 npm
npm i -g npm --registry=https://registry.npmmirror.com
# 安装 homebrew
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# 安装 git
brew install git
# 不自动转换换行符
git config --global core.autocrlf false
# 设置默认分支名为 main
git config --global init.defaultBranch main
```
设置 `~/.huskyrc`
```sh
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
```
对于 Windows 用户,请按照以下指引操作。
首先安装 [nvm-windows](https://github.com/coreybutler/nvm-windows/releases/download/1.1.8/nvm-setup.zip)[Git](https://git-scm.com/downloads)
然后使用 Windows Terminal 作为终端,Git Bash 作为 Shell,参考 [让 Win10 的终端更好用](https://sspai.com/post/63814)[配置 Windows Terminal](https://sspai.com/post/62167)
如果你正在使用 [Chocolatey](https://chocolatey.org/)[Scoop](https://scoop.sh/),你也可以通过命令安装,然后配置。
```sh
# 使用 Chocolatey
choco install nvm
choco install git
# 使用 Scoop
scoop install nvm
scoop install git
# 不自动转换换行符
git config --global core.autocrlf false
# 设置默认分支名为 main
git config --global init.defaultBranch main
# 设置镜像,加快下载速度
nvm node_mirror https://npmmirror.com/mirrors/node
nvm npm_mirror https://npmmirror.com/mirrors/npm
# 安装 node@lts
nvm install lts
# 使用 node@lts
nvm use lts
# 更新 npm
npm i -g npm --registry=https://registry.npmmirror.com
```
你可能需要配置 `~/.huskyrc`
其它系统请根据以上指引自行调整。
另外,你还需要安装最新的 [HBuilderX 正式版](https://www.dcloud.io/hbuilderx.html),用于申请一个 appid(DCloud 应用标识,也可以在 [网页](https://dev.dcloud.net.cn/) 上申请),以及把项目运行到真机或模拟器上。
### 安装与运行
```sh
# clone 项目到本地
git clone git@github.com:MillCloud/boilerplate-uni-app-vue3.git
# git clone git@gitee.com:MillCloud/boilerplate-uni-app-vue3.git
# 进入项目
cd boilerplate-uni-app-vue3
# 安装依赖
npm install --legacy-peer-deps
```
运行到支付宝小程序时,除运行 `npm run dev:mp-alipay`,还需要运行 `npm run watch:mp-alipay` 以保证样式正确。
## 使用
### 目录结构
```sh
.
├── .github # github 配置目录
├── .husky # husky 配置目录
├── public
├── scripts
│ ├── patch-mp-alipay.mts # 运行到支付宝小程序时的 patch
│ ├── update-manifest.mts # 配置 release-it 自动更新 manifest.json 的文件
├── src
│ ├── components # 全局组件目录
│ ├── composables # 全局组合式 API 目录
│ ├── constants # 固定数据目录
│ ├── helpers # 辅助方法目录
│ ├── pages # 页面视图目录
│ ├── static # 资产目录
│ ├── stores # 状态仓库目录
│ ├── styles # 全局样式和全局变量目录
│ ├── App.vue
│ ├── global.d.ts
│ ├── main.ts
│ └── shims-vue.d.ts
├── .commitlintrc.cjs # commitlint 配置文件
├── .editorconfig
├── .eslintrc.cjs # eslint 配置文件
├── .gitignore # git 配置文件
├── .lintstagedrc.cjs # lint-staged 配置文件
├── .markdownlint.json # markdownlint 配置文件
├── .npmrc # npm 配置文件
├── .prettierrc.cjs # prettier 配置文件
├── .release-it.cjs # release-it 配置文件
├── .stylelintrc.cjs # stylelint 配置文件
├── components.d.ts # 组件定义文件
├── index.html
├── package-lock.json
├── package.json
├── README.md
├── renovate.json # renovate 配置文件
└── tailwind.config.cjs # tailwindcss 配置文件
├── tsconfig.json # typescript 配置文件
└── vite.config.ts # vite 配置文件
```
### VSCode 支持
你可以参考 [插件](https://modyqyw.top/summarize/environment/#%E6%8F%92%E4%BB%B6)[settings.json](https://modyqyw.top/summarize/environment/#settings-json)
### 路由
uni-app 使用 [pages.json](./src/pages.json) 配置路由,请查看 [文档](https://uniapp.dcloud.io/collocation/pages)
### 状态
使用 [pinia](https://pinia.vuejs.org/) 作为状态管理工具。
### 请求
使用 [uni.request](https://uniapp.dcloud.io/api/request/request.html) 作为底层请求,使用 [vue-query](https://vue-query.vercel.app/) 管理底层请求。
查看 [@/helpers/request.ts](./src/helpers/request.ts) 了解预设配置。
如果不喜欢 vue-query,也可以自行配置 [swrv](https://github.com/Kong/swrv) 使用。
### 测试
WIP
- [vitest](https://vitest.dev/)
- [cypress](https://www.cypress.io/)
- [playwright](https://playwright.dev/)
- [@testing-library/vue](https://testing-library.com/docs/vue-testing-library/intro/)
### 部署
- 确认所有环境变量和模式相关的地方已经配置完成,参考 [vite 文档 - 环境变量和模式](https://cn.vitejs.dev/guide/env-and-mode.html)[vite-plugin-env-compatible](https://github.com/IndexXuan/vite-plugin-env-compatible)
- 运行 `npm run release`,更新版本号并上传 `dist` 目录下的内容。
- 更多自定义可以参考 `release-it` 文档说明,使用 `node` 运行脚本完成操作。
{
"version": "1",
"prompt": "template",
"title": "服务协议和隐私政策",
"message": "请你务必审慎阅读、充分理解“服务协议”和“隐私政策”各条款,包括但不限于:为了更好的向你提供服务,我们需要收集你的设备标识、操作日志等信息用于分析、优化应用性能。<br/><br/>你可阅读<a href=\"https:\/\/www.baidu.com\">《服务协议》</a>和<a href=\"https:\/\/www.baidu.com\">《隐私政策》</a>了解详细信息。如果你同意,请点击下面按钮开始接受我们的服务。",
"buttonAccept": "同意并接受",
"buttonRefuse": "暂不同意",
"second": {
"title": "确认提示",
"message": "进入应用前,你需先同意<a href=\"https:\/\/www.baidu.com\">《服务协议》</a>和<a href=\"https:\/\/www.baidu.com\">《隐私政策》</a>,否则将退出应用。",
"buttonAccept": "同意并继续",
"buttonRefuse": "退出应用"
},
"styles": {
"borderRadius": "4px"
}
}
// generated by unplugin-vue-components
// We suggest you to commit this file into source control
// Read more: https://github.com/vuejs/vue-next/pull/3399
declare module 'vue' {
export interface GlobalComponents {
VSpacer: typeof import('./src/components/VSpacer.vue')['default'];
}
}
export {};
<!DOCTYPE html>
<html lang="zh-Hans">
<head>
<meta charset="UTF-8" />
<meta name="renderer" content="webkit" />
<meta name="force-rendering" content="webkit" />
<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1" />
<script>
var coverSupport =
'CSS' in window &&
typeof CSS.supports === 'function' &&
(CSS.supports('top: env(a)') || CSS.supports('top: constant(a)'));
document.write(
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
(coverSupport ? ', viewport-fit=cover' : '') +
'" />',
);
</script>
<title></title>
<!--preload-links-->
<!--app-context-->
</head>
<body>
<div id="app"><!--app-html--></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"name": "boilerplate-uni-app-vue3",
"version": "0.0.0",
"scripts": {
"build:app": "uni build -p app",
"build:custom": "uni build -p",
"build:h5": "uni build",
"build:h5:ssr": "uni build --ssr",
"build:mp-alipay": "cross-env UNI_OUTPUT_DIR=dist/mp-alipay uni build -p mp-alipay",
"build:mp-baidu": "cross-env UNI_OUTPUT_DIR=dist/mp-baidu uni build -p mp-baidu",
"build:mp-kuaishou": "cross-env UNI_OUTPUT_DIR=dist/mp-kuaishou uni build -p mp-kuaishou",
"build:mp-lark": "cross-env UNI_OUTPUT_DIR=dist/mp-lark uni build -p mp-lark",
"build:mp-qq": "cross-env UNI_OUTPUT_DIR=dist/mp-qq uni build -p mp-qq",
"build:mp-toutiao": "cross-env UNI_OUTPUT_DIR=dist/mp-toutiao uni build -p mp-toutiao",
"build:mp-weixin": "cross-env UNI_OUTPUT_DIR=dist/mp-weixin uni build -p mp-weixin",
"build:quickapp-webview": "cross-env UNI_OUTPUT_DIR=dist/quickapp-webview uni build -p quickapp-webview",
"build:quickapp-webview-huawei": "cross-env UNI_OUTPUT_DIR=dist/quickapp-webview-huawei uni build -p quickapp-webview-huawei",
"build:quickapp-webview-union": "cross-env UNI_OUTPUT_DIR=dist/quickapp-webview-union uni build -p quickapp-webview-union",
"check:deps": "ncu",
"check:types": "vue-tsc --noEmit",
"commit": "git-cz",
"dev:app": "uni -p app",
"dev:custom": "uni -p",
"dev:h5": "uni",
"dev:h5:ssr": "uni --ssr",
"dev:mp-alipay": "cross-env UNI_OUTPUT_DIR=dist/mp-alipay uni -p mp-alipay",
"dev:mp-baidu": "cross-env UNI_OUTPUT_DIR=dist/mp-baidu uni -p mp-baidu",
"dev:mp-kuaishou": "cross-env UNI_OUTPUT_DIR=dist/mp-kuaishou uni -p mp-kuaishou",
"dev:mp-lark": "cross-env UNI_OUTPUT_DIR=dist/mp-lark uni -p mp-lark",
"dev:mp-qq": "cross-env UNI_OUTPUT_DIR=dist/mp-qq uni -p mp-qq",
"dev:mp-toutiao": "cross-env UNI_OUTPUT_DIR=dist/mp-toutiao uni -p mp-toutiao",
"dev:mp-weixin": "cross-env UNI_OUTPUT_DIR=dist/mp-weixin uni -p mp-weixin",
"dev:quickapp-webview": "cross-env UNI_OUTPUT_DIR=dist/quickapp-webview uni -p quickapp-webview",
"dev:quickapp-webview-huawei": "cross-env UNI_OUTPUT_DIR=dist/quickapp-webview-huawei uni -p quickapp-webview-huawei",
"dev:quickapp-webview-union": "cross-env UNI_OUTPUT_DIR=dist/quickapp-webview-union uni -p quickapp-webview-union",
"lint": "npm run lint:eslint && npm run lint:markdownlint && npm run lint:stylelint && vue-tsc --noEmit",
"lint:eslint": "eslint . --fix --ext=.js,.cjs,.mjs,.jsx,.ts,.cts,.mts,.tsx,.vue,.svelte,.yaml,.yml,.json,.jsonc,.json5 --ignore-path=.gitignore",
"lint:markdownlint": "markdownlint . --fix --ignore-path=.gitignore",
"lint:stylelint": "stylelint \"./**/*.{css,less,scss,sass,vue,svelte}\" --fix --allow-empty-input --ignore-path=.gitignore",
"prepare": "is-ci || husky install",
"release": "release-it",
"watch:mp-alipay": "nodemon --watch dist/mp-alipay/pages --ext axml --exec \"esmo\" ./scripts/patch-mp-alipay.mts"
},
"config": {
"commitizen": {
"path": "@commitlint/prompt"
}
},
"dependencies": {
"@dcloudio/uni-app": "^3.0.0-alpha-3040420220402003",
"@dcloudio/uni-app-plus": "^3.0.0-alpha-3040420220402003",
"@dcloudio/uni-components": "^3.0.0-alpha-3040420220402003",
"@dcloudio/uni-h5": "^3.0.0-alpha-3040420220402003",
"@dcloudio/uni-mp-alipay": "^3.0.0-alpha-3040420220402003",
"@dcloudio/uni-mp-baidu": "^3.0.0-alpha-3040420220402003",
"@dcloudio/uni-mp-kuaishou": "^3.0.0-alpha-3040420220402003",
"@dcloudio/uni-mp-lark": "^3.0.0-alpha-3040420220402003",
"@dcloudio/uni-mp-qq": "^3.0.0-alpha-3040420220402003",
"@dcloudio/uni-mp-toutiao": "^3.0.0-alpha-3040420220402003",
"@dcloudio/uni-mp-weixin": "^3.0.0-alpha-3040420220402003",
"@dcloudio/uni-quickapp-webview": "^3.0.0-alpha-3040420220402003",
"@dcloudio/uni-ui": "^1.4.14",
"@vueuse/core": "^8.2.6",
"@vueuse/integrations": "^8.2.6",
"change-case": "^4.1.2",
"color": "^4.2.3",
"dayjs": "^1.11.1",
"esno": "^0.14.1",
"lodash-es": "^4.17.21",
"pinia": "^2.0.13",
"query-string": "^7.1.1",
"ramda": "^0.28.0",
"statuses": "^2.0.1",
"thorui-uni": "^1.7.2",
"vue": "^3.2.33",
"vue-query": "^1.22.3"
},
"devDependencies": {
"@babel/core": "^7.17.9",
"@babel/eslint-parser": "^7.17.0",
"@commitlint/cli": "^16.2.3",
"@commitlint/config-conventional": "^16.2.1",
"@commitlint/prompt": "^16.2.3",
"@dcloudio/types": "^2.6.4",
"@dcloudio/uni-automator": "^3.0.0-alpha-3040420220402003",
"@dcloudio/uni-cli-shared": "^3.0.0-alpha-3040420220402003",
"@dcloudio/vite-plugin-uni": "^3.0.0-alpha-3040420220402003",
"@modyqyw/fabric": "^5.0.0-0",
"@modyqyw/vite-plugin-eslint": "^1.2.0",
"@tailwindcss/aspect-ratio": "^0.4.0",
"@tailwindcss/line-clamp": "^0.3.1",
"@tailwindcss/typography": "^0.5.2",
"@types/color": "^3.0.3",
"@types/lodash-es": "^4.17.6",
"@types/ramda": "^0.28.11",
"@types/statuses": "^2.0.0",
"@types/tailwindcss": "^3.0.10",
"@typescript-eslint/eslint-plugin": "^5.20.0",
"@typescript-eslint/parser": "^5.20.0",
"@vitejs/plugin-vue": "^2.3.1",
"@vitejs/plugin-vue-jsx": "^1.3.10",
"@vue/tsconfig": "^0.1.3",
"commitizen": "^4.2.4",
"cross-env": "^7.0.3",
"eslint": "^8.13.0",
"husky": "^7.0.4",
"is-ci": "^3.0.1",
"lint-staged": "^12.3.8",
"markdownlint-cli": "^0.31.1",
"npm-check-updates": "^12.5.9",
"picocolors": "^1.0.0",
"postcss": "^8.4.12",
"postcss-preset-env": "^7.4.3",
"prettier": "^2.6.2",
"release-it": "^14.14.2",
"rimraf": "^3.0.2",
"sass": "^1.50.1",
"shelljs": "^0.8.5",
"stylelint": "^14.7.1",
"tailwindcss": "^3.0.24",
"type-fest": "^2.12.2",
"typescript": "^4.6.3",
"vite": "^2.9.5",
"vite-plugin-env-compatible": "^1.1.1",
"vite-plugin-inspect": "^0.5.0",
"vite-plugin-stylelint": "^2.1.0",
"vue-tsc": "^0.34.7"
}
}
{
"extends": ["config:base", ":preserveSemverRanges"]
}
/* eslint-disable no-console */
import fs from 'node:fs';
import path from 'node:path';
console.log('Patching dist/mp-alipay/pages/**/*.axml ...');
const handleAddPageMeta = (pagesDirPath: string) => {
// make sure exist
if (!fs.existsSync(pagesDirPath)) {
console.log('Done with not exist.');
return;
}
// get pages dir
const pagesDir = fs.readdirSync(pagesDirPath);
// deal with .axml
const axmls = pagesDir.filter((item) => item.endsWith('.axml'));
for (const axml of axmls) {
const axmlPath = path.resolve(pagesDirPath, axml);
const axmlContent = fs.readFileSync(axmlPath, {
encoding: 'utf8',
});
if (!axmlContent.startsWith('<page-meta root-font-size="16px"></page-meta>')) {
fs.writeFileSync(axmlPath, `<page-meta root-font-size="16px"></page-meta>${axmlContent}`);
}
}
// deal with folder
const dirs = pagesDir.filter((item) => !item.includes('.'));
for (const dir of dirs) {
handleAddPageMeta(path.resolve(pagesDirPath, dir));
}
console.log('Done with exists.');
};
handleAddPageMeta(path.resolve('dist', 'mp-alipay', 'pages'));
/* eslint-enable no-console */
import fs from 'node:fs';
import pkg from '../package.json';
import manifest from '../src/manifest.json';
manifest.versionName = pkg.version;
manifest.versionCode = (Number.parseInt(manifest.versionCode, 10) + 1).toString();
if (manifest['quickapp-webview']) {
manifest['quickapp-webview'].versionName = manifest.versionName;
manifest['quickapp-webview'].versionCode = manifest.versionCode;
}
fs.writeFileSync('./src/manifest.json', `${JSON.stringify(manifest, null, 2)}\n`);
<script setup lang="ts">
import { onLaunch, onShow, onHide } from '@dcloudio/uni-app';
onLaunch(() => {
console.log('App Launch');
});
onShow(() => {
console.log('App Show');
});
onHide(() => {
console.log('App Hide');
});
</script>
<style lang="scss">
@import './styles/variables';
@import './styles/preflight';
@import './styles/tailwind';
@import './styles/global';
</style>
<template>
<view class="flex-auto" />
</template>
import VSpacer from './VSpacer.vue';
import type { Plugin } from 'vue';
const Components: Plugin = {
install: (app) => {
app.component('VSpacer', VSpacer);
},
};
export default Components;
import pkg from '@/../package.json';
export { default as pkg } from '@/../package.json';
export const Headers = {
Accept: 'application/json',
'Content-Type': 'application/json; charset=utf-8',
'X-Version': `${pkg.name}/${pkg.version}`,
};
export const TokenKey = 'token';
export const DefaultToken = '';
export const PageLimitKey = 'pageLimit';
export const DefaultPageLimit = 10;
declare global {
interface IResponseData {
success: boolean;
code: string;
message: string;
[propName: string]: any;
}
type BaseRequestHeaders = Record<string, string | number | boolean>;
type BaseResponseHeaders = Record<string, string> & {
'set-cookie'?: string[];
};
type BaseData = string | AnyObject | ArrayBuffer;
interface BaseRequestConfig<D = BaseData>
extends Omit<UniApp.RequestOptions, 'success' | 'fail' | 'complete'> {
url?: string;
data?: D;
params?: string | AnyObject;
headers?: BaseRequestHeaders;
}
type BaseResponse<T = BaseData, D = BaseData> = UniApp.RequestSuccessCallbackResult & {
data: T;
status?: number;
statusText?: string;
headers?: BaseResponseHeaders;
config?: BaseRequestConfig<D>;
request?: any;
};
type BaseError<T = BaseData, D = BaseData> = UniApp.GeneralCallbackResult & {
config?: BaseRequestConfig<D>;
code?: string;
request?: any;
response?: BaseResponse<T, D>;
};
interface IResponse extends BaseResponse<IResponseData> {}
interface IResponseError extends BaseError<IResponseData> {
response?: IResponse;
}
interface IRequestConfig extends BaseRequestConfig {
showError?: boolean;
showErrorType?: 'toast' | 'modal';
}
}
export {};
export const showActionSheet = (options: UniApp.ShowActionSheetOptions) =>
uni.showActionSheet({
itemColor: '#303133',
...options,
});
export * from './action-sheet';
export * from './loading';
export * from './modal';
export * from './request';
export * from './storage';
export * from './toast';
export const showLoading = (options: UniApp.ShowLoadingOptions) => {
uni.showLoading({
title: '加载中',
mask: true,
...options,
});
return () => uni.hideLoading();
};
export const hideLoading = () => uni.hideLoading();
export const showModal = (options: UniApp.ShowModalOptions) =>
uni.showModal({
title: '提示',
cancelColor: '#303133',
confirmColor: '#409eff',
...options,
});
import qs from 'query-string';
import { QueryClient, QueryCache, MutationCache } from 'vue-query';
import { Headers } from '@/constants';
import { showModal } from './modal';
import { getToken, setToken } from './storage';
import { showToast } from './toast';
import type { VueQueryPluginOptions } from 'vue-query';
const reSignInCodes = new Set(['LOGIN_REQUIRED', 'LOGIN_TOKEN_INVALID', 'LOGIN_SESSION_EXPIRED']);
// https://github.com/dcloudio/uni-app/issues/1710#issuecomment-633219364
export async function request<T = BaseData, R = BaseResponse<T>, D = BaseData>(
config: BaseRequestConfig<D>,
) {
const baseURL =
process.env.VITE_REQUEST_BASE_URL || 'https://jsonplaceholder.typicode.com/todos/';
const stringifiedParams = qs.stringify(
Object.fromEntries(
Object.entries(config.params ?? {}).filter(
([, v]) => !['', 'undefined', 'null', undefined, null].includes(v?.toString() ?? v),
),
),
);
const params = stringifiedParams ? `?${stringifiedParams}` : '';
const url =
config.url?.startsWith('https://') || config.url?.startsWith('http://')
? `${config.url}${params}`
: `${baseURL}${config.url}${params}`;
return new Promise<R>((resolve, reject) => {
uni.request({
...config,
url,
header: {
...Headers,
...config.header,
...config.headers,
token: getToken(),
'X-Token': getToken(),
'X-Access-Token': getToken(),
},
success: (response) => resolve(response as unknown as R),
fail: (error) => reject(error),
});
});
}
export const showError = ({
error,
type = 'modal',
confirm,
}: {
error?: IResponseError;
type?: 'toast' | 'modal';
confirm?: () => void;
} = {}) => {
const contents = [];
const code =
error?.code ??
// @ts-ignore
error?.statusCode ??
// @ts-ignore
error?.status ??
error?.response?.data?.code ??
error?.response?.data?.statusCode ??
error?.response?.data?.status ??
// @ts-ignore
error?.response?.code ??
error?.response?.statusCode ??
error?.response?.status ??
'';
if (code) {
contents.push(`错误代码:${code}`);
}
// @ts-ignore
const url = error?.url ?? error?.config?.url ?? error?.request?.url ?? '';
if (url) {
contents.push(`请求地址:${url}`);
}
const message =
// @ts-ignore
error?.message ??
error?.errMsg ??
error?.response?.data?.message ??
error?.response?.data?.errMsg ??
error?.response?.data?.msg ??
'';
if (message) {
contents.push(`错误信息:${message}`);
}
const content = contents.length <= 1 ? contents[0].split(':')[1] : `${contents.join(',')}。`;
if (type === 'toast') {
showToast({
title: content,
duration: 3000,
});
if (confirm) {
setTimeout(() => {
confirm();
}, 3000);
}
return;
}
if (type === 'modal') {
showModal({
title: '错误',
content,
success: (result) => {
if (result && confirm) {
confirm();
}
},
});
}
};
export const queryClient = new QueryClient({
queryCache: new QueryCache({
onError: (error) => {
showError({
error: error as IResponseError,
});
},
}),
mutationCache: new MutationCache({
onError: (error) => {
showError({
error: error as IResponseError,
});
},
}),
defaultOptions: {
queries: {
queryFn: async ({ queryKey }) => {
// console.log('');
// console.log('queryKey', queryKey);
// console.log('');
const urlParams = Array.isArray(queryKey[1]) ? queryKey[1] : [];
const url = urlParams.reduce(
(acc, cur, idx) => acc.replace(`:${idx}`, cur.toString()),
(queryKey[0] as any).toString(),
);
const params = queryKey[2] as Record<string, any>;
const config = queryKey[3] as IRequestConfig;
const { data } = await request<IResponseData>({
method: 'GET',
url,
params,
...config,
});
if (!(data?.success ?? true)) {
if (reSignInCodes.has(data.code)) {
setToken('');
showError({
error: {
errMsg: '请重新登录。',
},
});
} else if (config?.showError ?? true) {
showError({
error: data as unknown as IResponseError,
type: config?.showErrorType,
});
}
}
return data;
},
refetchOnWindowFocus: false,
retry: (failureCount, error) => {
if (
[403, 404, 500].includes(
(error as IResponseError).response?.statusCode ??
(error as IResponseError).response?.status ??
// @ts-ignore
(error as IResponseError).response?.code ??
200,
)
) {
return false;
}
return failureCount < 3;
},
},
mutations: {
mutationFn: async (variables) => {
// console.log('');
// console.log('variables', variables);
// console.log('');
const config = { ...(variables as IRequestConfig) };
const { data } = await request<IResponseData>({
method: 'POST',
...config,
});
if (!(data?.success ?? true)) {
if (reSignInCodes.has(data.code)) {
setToken('');
showError({
error: {
errMsg: '请重新登录。',
},
});
} else if (config?.showError ?? true) {
showError({
error: data as unknown as IResponseError,
type: config?.showErrorType,
});
}
}
return data;
},
retry: (failureCount, error) => {
if (
[403, 404, 500].includes(
(error as IResponseError).response?.statusCode ??
(error as IResponseError).response?.status ??
// @ts-ignore
(error as IResponseError).response?.code ??
200,
)
) {
return false;
}
return failureCount < 3;
},
},
},
});
export const vueQueryPluginOptions: VueQueryPluginOptions = {
queryClient,
};
import { TokenKey, DefaultToken } from '../constants';
export const getToken = () => (uni.getStorageSync(TokenKey) as string | null) ?? DefaultToken;
export const setToken = (token = DefaultToken) => uni.setStorageSync(TokenKey, token);
export const showToast = (options: UniApp.ShowToastOptions) =>
uni.showToast({
...options,
});
export const hideToast = () => uni.hideToast();
import dayjs from 'dayjs';
import 'dayjs/locale/zh-cn';
import customParseFormat from 'dayjs/plugin/customParseFormat';
import { createPinia } from 'pinia';
import { createSSRApp } from 'vue';
import { VueQueryPlugin } from 'vue-query';
import App from './App.vue';
import Components from './components';
import { vueQueryPluginOptions } from './helpers';
import '@/styles/preflight.css';
import '@/styles/tailwind.css';
import '@/styles/global.scss';
dayjs.locale('zh-cn');
dayjs.extend(customParseFormat);
export function createApp() {
const app = createSSRApp(App)
.use(createPinia())
.use(VueQueryPlugin, vueQueryPluginOptions)
.use(Components);
return { app };
}
{
"name": "boilerplate-uni-app-vue3",
"appid": "",
"description": "A boilerplate for uni-app.",
"versionName": "0.0.0",
"versionCode": "0",
"transformPx": false,
"networkTimeout": {
"request": 60000,
"connectSocket": 60000,
"uploadFile": 60000,
"downloadFile": 60000
},
"debug": false,
"uniStatistics": {
"enable": false
},
"app-plus": {
"compatible": {
"ignoreVersion": true
},
"usingComponents": true,
"splashscreen": {
"alwaysShowBeforeRender": true,
"autoclose": true,
"waiting": true,
"delay": 0
},
"modules": {},
"compilerVersion": 3,
"nvueCompiler": "uni-app",
"nvueLaunchMode": "normal",
"nvue": {
"flex-direction": "column"
},
"distribute": {
"android": {
"abiFilters": ["armeabi-v7a", "arm64-v8a", "x86"],
"splashscreen": {
"alwaysShowBeforeRender": true,
"autoclose": true,
"waiting": true,
"delay": 0
},
"minSdkVersion": 21,
"targetSdkVersion": 26,
"permissionExternalStorage": {
"request": "once",
"prompt": "应用保存运行状态等信息,需要获取读写手机存储权限,系统可能提示为访问设备上的照片、媒体内容和文件,请允许。"
},
"permissionPhoneState": {
"request": "once",
"prompt": "为保证正常安全使用,需要获取设备识别码使用权限,系统可能提示为获取手机号码,请允许。"
},
"permissions": [
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.INSTALL_PACKAGES\"/>",
"<uses-permission android:name=\"android.permission.INTERNET\"/>",
"<uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\"/>",
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
"<uses-permission android:name=\"android.permission.REQUEST_INSTALL_PACKAGES\"/>",
"<uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\"/>",
"<uses-permission android:name=\"com.asus.msa.SupplementaryDID.ACCESS\"/>",
"<uses-permission android:name=\"com.huawei.android.launcher.permission.CHANGE_BADGE\"/>"
]
},
"ios": {},
"orientation": ["portrait-primary"],
"splashscreen": {
"useOriginalMsgbox": true
},
"sdkConfigs": {
"ad": {}
}
}
},
"h5": {},
"mp-weixin": {
"appid": "touristappid",
"usingComponents": true,
"libVersion": "",
"permission": {},
"setting": {
"es6": false,
"enhance": false,
"nodeModules": false,
"postcss": false,
"minifyWXSS": false,
"minified": false,
"uglifyFileName": false,
"urlCheck": true,
"showShadowRootInWxmlPanel": true,
"preloadBackgroundData": false,
"compileHotReLoad": false,
"bundle": false,
"checkSiteMap": false,
"checkInvalidKey": false
}
},
"mp-alipay": {
"usingComponents": true,
"component2": true,
"axmlStrictCheck": false,
"enableParallelLoader": true,
"enableAppxNg": true
},
"mp-baidu": {
"appid": "",
"usingComponents": true,
"setting": {
"urlCheck": true
}
},
"mp-toutiao": {
"appid": "",
"usingComponents": true,
"permission": {},
"setting": {
"es6": false,
"minified": false,
"urlCheck": true
}
},
"mp-qq": {
"appid": "",
"usingComponents": true,
"permission": {}
},
"quickapp-webview": {
"icon": "/static/logo.png",
"package": "cn.millcloud",
"versionName": "0.0.0",
"versionCode": "1"
},
"quickapp-webview-union": {
"minPlatformVersion": 1063
},
"quickapp-webview-huawei": {
"minPlatformVersion": 1070
},
"vueVersion": "3"
}
{
"easycom": {
"autoscan": true,
"custom": {
"^uni-(.*)": "@dcloudio/uni-ui/lib/uni-$1/uni-$1.vue",
"^tui-(.*)": "thorui-uni/lib/thorui/tui-$1/tui-$1.vue"
}
},
"pages": [
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "uni-app"
}
}
],
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "uni-app",
"navigationBarBackgroundColor": "#F8F8F8",
"backgroundColor": "#F8F8F8"
}
}
<template>
<view class="container items-center justify-center">
<image class="m-4 mx-auto block h-20 w-20" src="/static/logo.png" />
<view class="flex w-full justify-center">
<text class="text-xl">{{ title }}</text>
</view>
<view class="flex w-full justify-between">
<button
class="m-4 flex h-8 flex-auto items-center justify-center rounded border border-solid border-gray-300 bg-gray-100 px-4 transition"
hover-class="bg-primary border-primary text-white"
>
default
</button>
<button
class="m-4 flex h-8 flex-auto items-center justify-center rounded border border-solid border-primary bg-primary px-4 text-white transition"
hover-class="bg-primary-darken-1 border-primary-darken-1"
>
primary
</button>
</view>
<view class="flex w-full justify-center">
<tui-button class="m-4 w-full">thor-ui</tui-button>
</view>
<view class="flex w-full justify-center p-4">
<template v-if="isLoading">Loading...</template>
<template v-else>{{ data }}</template>
</view>
</view>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { useQuery } from 'vue-query';
const title = ref('Hello UniApp');
const id = ref(1);
const { data, isLoading } = useQuery<IResponseData, IResponseError>([id]);
</script>
import { defineStore } from 'pinia';
export const useCounterStore = defineStore({
id: 'counter',
state: () => ({
counter: 0,
}),
getters: {
doubleCount: (state) => state.counter * 2,
},
actions: {
increment() {
this.counter += 1;
},
},
});
export * from './counter';
html,
body,
page {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Helvetica,
"PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "微软雅黑", Arial, "Noto Sans", sans-serif,
"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
font-size: 16px;
line-height: 1.5;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.container {
position: absolute;
top: 0;
left: 0;
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
}
/* stylelint-disable property-no-vendor-prefix, no-descending-specificity */
/* based on ress.css v5.0.2 */
/* https://resset.dev/ */
/* for miniprogram */
button,
button::after {
all: unset;
}
html,
body,
page,
cover-image,
cover-view,
match-media,
movable-area,
movable-view,
scroll-view,
swiper,
swiper-item,
view,
icon,
progress,
rich-text,
text,
button,
checkbox,
checkbox-group,
editor,
form,
input,
label,
picker,
picker-view,
picker-view-column,
radio,
radio-group,
slider,
switch,
textarea,
functional-page-navigator,
navigator,
audio,
camera,
image,
live-player,
live-pusher,
video,
voip-room,
map,
canvas,
ad,
ad-custom,
official-account,
open-data,
web-view,
navigation-bar,
page-meta,
::before,
::after {
box-sizing: inherit;
background-repeat: no-repeat;
}
html,
page {
box-sizing: border-box;
-webkit-text-size-adjust: 100%;
word-break: normal;
-moz-tab-size: 4;
tab-size: 4;
}
::before,
::after {
text-decoration: inherit;
vertical-align: inherit;
}
html,
body,
page,
cover-image,
cover-view,
match-media,
movable-area,
movable-view,
scroll-view,
swiper,
swiper-item,
view,
icon,
progress,
rich-text,
text,
button,
checkbox,
checkbox-group,
editor,
form,
input,
label,
picker,
picker-view,
picker-view-column,
radio,
radio-group,
slider,
switch,
textarea,
functional-page-navigator,
navigator,
audio,
camera,
image,
live-player,
live-pusher,
video,
voip-room,
map,
canvas,
ad,
ad-custom,
official-account,
open-data,
web-view,
navigation-bar,
page-meta {
padding: 0;
margin: 0;
}
hr {
height: 0;
overflow: visible;
color: inherit;
}
details,
main {
display: block;
}
summary {
display: list-item;
}
small {
font-size: 80%;
}
[hidden] {
display: none;
}
abbr[title] {
text-decoration: underline;
text-decoration: underline dotted;
border-bottom: none;
}
a {
background-color: transparent;
}
a:active,
a:hover {
outline-width: 0;
}
code,
kbd,
pre,
samp {
font-family: monospace;
}
pre {
font-size: 1em;
}
b,
strong {
font-weight: bolder;
}
sub,
sup {
position: relative;
font-size: 75%;
line-height: 0;
vertical-align: baseline;
}
sub {
bottom: -0.25em;
}
sup {
top: -0.5em;
}
table {
text-indent: 0;
border-color: inherit;
}
iframe {
border-style: none;
}
input {
border-radius: 0;
}
[type="number"]::-webkit-inner-spin-button,
[type="number"]::-webkit-outer-spin-button {
height: auto;
}
[type="search"] {
-webkit-appearance: textfield;
outline-offset: -2px;
}
[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
textarea {
overflow: auto;
resize: vertical;
}
button,
input,
optgroup,
select,
textarea {
font: inherit;
}
optgroup {
font-weight: bold;
}
button {
-webkit-tap-highlight-color: transparent; /* for miniprogram */
overflow: visible;
}
button,
select {
text-transform: none;
}
button,
[type="button"],
[type="reset"],
[type="submit"],
[role="button"] {
cursor: pointer;
}
button::-moz-focus-inner,
[type="button"]::-moz-focus-inner,
[type="reset"]::-moz-focus-inner,
[type="submit"]::-moz-focus-inner {
padding: 0;
border-style: none;
}
/* button:-moz-focusring,
[type="button"]::-moz-focus-inner,
[type="reset"]::-moz-focus-inner,
[type="submit"]::-moz-focus-inner {
outline: 1px dotted ButtonText;
} */
/* remove these if cause bugs */
/* button, */
html [type="button"],
page [type="button"],
[type="reset"],
[type="submit"] {
-webkit-appearance: button;
}
button,
input,
select,
textarea {
background-color: transparent;
border-style: none;
}
a:focus,
button:focus,
input:focus,
select:focus,
textarea:focus {
outline-width: 0;
}
select {
-moz-appearance: none;
-webkit-appearance: none;
}
select::-ms-expand {
display: none;
}
select::-ms-value {
color: currentcolor;
}
legend {
display: table;
max-width: 100%;
color: inherit;
white-space: normal;
border: 0;
}
::-webkit-file-upload-button {
font: inherit;
color: inherit;
-webkit-appearance: button;
}
[disabled] {
cursor: default;
}
img,
image {
border-style: none;
}
progress {
vertical-align: baseline;
}
[aria-busy="true"] {
cursor: progress;
}
[aria-controls] {
cursor: pointer;
}
[aria-disabled="true"] {
cursor: default;
}
/* disabled to avoid import invalid * */
/* @tailwind base; */
/* write styles manually */
html,
body,
page,
cover-image,
cover-view,
match-media,
movable-area,
movable-view,
scroll-view,
swiper,
swiper-item,
view,
icon,
progress,
rich-text,
text,
button,
checkbox,
checkbox-group,
editor,
form,
input,
label,
picker,
picker-view,
picker-view-column,
radio,
radio-group,
slider,
switch,
textarea,
functional-page-navigator,
navigator,
audio,
camera,
image,
live-player,
live-pusher,
video,
voip-room,
map,
canvas,
ad,
ad-custom,
official-account,
open-data,
web-view,
navigation-bar,
page-meta,
::before,
::after {
--tw-translate-x: 0;
--tw-translate-y: 0;
--tw-rotate: 0;
--tw-skew-x: 0;
--tw-skew-y: 0;
--tw-scale-x: 1;
--tw-scale-y: 1;
--tw-pan-x: ;
--tw-pan-y: ;
--tw-pinch-zoom: ;
--tw-scroll-snap-strictness: proximity;
--tw-ordinal: ;
--tw-slashed-zero: ;
--tw-numeric-figure: ;
--tw-numeric-spacing: ;
--tw-numeric-fraction: ;
--tw-ring-inset: ;
--tw-ring-offset-width: 0;
--tw-ring-offset-color: #fff;
--tw-ring-color: rgb(59 130 246 / 50%);
--tw-ring-offset-shadow: 0 0 #0000;
--tw-ring-shadow: 0 0 #0000;
--tw-shadow: 0 0 #0000;
--tw-shadow-colored: 0 0 #0000;
--tw-blur: ;
--tw-brightness: ;
--tw-contrast: ;
--tw-grayscale: ;
--tw-hue-rotate: ;
--tw-invert: ;
--tw-saturate: ;
--tw-sepia: ;
--tw-drop-shadow: ;
--tw-backdrop-blur: ;
--tw-backdrop-brightness: ;
--tw-backdrop-contrast: ;
--tw-backdrop-grayscale: ;
--tw-backdrop-hue-rotate: ;
--tw-backdrop-invert: ;
--tw-backdrop-opacity: ;
--tw-backdrop-saturate: ;
--tw-backdrop-sepia: ;
}
@tailwind components;
@tailwind utilities;
/*
* uni-app uni.scss 内容,可直接修改
* 参考 https://uniapp.dcloud.io/collocation/uni-scss
*/
// 行为相关色
$uni-color-primary: #007aff;
$uni-color-success: #4cd964;
$uni-color-warning: #f0ad4e;
$uni-color-error: #dd524d;
// 文字基本色
$uni-text-color: #333; // 基本色
$uni-text-color-inverse: #fff; // 反色
$uni-text-color-grey: #999; // 辅助灰色,如加载更多的提示信息
$uni-text-color-placeholder: #808080;
$uni-text-color-disable: #c0c0c0;
// 背景色
$uni-bg-color: #fff;
$uni-bg-color-grey: #f8f8f8;
$uni-bg-color-hover: #f1f1f1; // 点击状态色
$uni-bg-color-mask: rgba(0, 0, 0, 40%); // 遮罩色
// 边框色
$uni-border-color: #c8c7cc;
// 文字尺寸
$uni-font-size-sm: 24rpx;
$uni-font-size-base: 28rpx;
$uni-font-size-lg: 32rpx;
// 图片尺寸
$uni-img-size-sm: 40rpx;
$uni-img-size-base: 52rpx;
$uni-img-size-lg: 80rpx;
// 边框圆角尺寸
$uni-border-radius-sm: 4rpx;
$uni-border-radius-base: 6rpx;
$uni-border-radius-lg: 12rpx;
$uni-border-radius-circle: 50%;
// 内边距尺寸
$uni-spacing-row-sm: 10rpx;
$uni-spacing-row-base: 20rpx;
$uni-spacing-row-lg: 30rpx;
// 外边距尺寸
$uni-spacing-col-sm: 8rpx;
$uni-spacing-col-base: 16rpx;
$uni-spacing-col-lg: 24rpx;
// 透明度变量
$uni-opacity-disabled: 0.3; // 组件禁用态的透明度
// 文章场景变量
$uni-color-title: #2c405a; // 文章标题色
$uni-font-size-title: 40rpx;
$uni-color-subtitle: #555; // 二级标题色
$uni-font-size-subtitle: 36rpx;
$uni-color-paragraph: #3f536e; // 文章段落色
$uni-font-size-paragraph: 30rpx;
/*
* uview-ui theme.scss 内容,可直接修改
* 参考 https://www.uviewui.com/components/color.html
*/
$u-main-color: #303133;
$u-content-color: #606266;
$u-tips-color: #909193;
$u-light-color: #c0c4cc;
$u-border-color: #dadbde;
$u-bg-color: #f3f4f6;
$u-disabled-color: #c8c9cc;
$u-primary: #3c9cff;
$u-primary-dark: #398ade;
$u-primary-disabled: #9acafc;
$u-primary-light: #ecf5ff;
$u-warning: #f9ae3d;
$u-warning-dark: #f1a532;
$u-warning-disabled: #f9d39b;
$u-warning-light: #fdf6ec;
$u-success: #5ac725;
$u-success-dark: #53c21d;
$u-success-disabled: #a9e08f;
$u-success-light: #f5fff0;
$u-error: #f56c6c;
$u-error-dark: #e45656;
$u-error-disabled: #f7b2b2;
$u-error-light: #fef0f0;
$u-info: #909399;
$u-info-dark: #767a82;
$u-info-disabled: #c4c6c9;
$u-info-light: #f4f4f5;
@mixin flex($direction: row) {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: $direction;
}
const color = require('color');
const tailwindcssTypography = require('@tailwindcss/typography');
const tailwindcssLineClamp = require('@tailwindcss/line-clamp');
const tailwindcssAspectRatio = require('@tailwindcss/aspect-ratio');
// Remember to update colors in ./src/styles/variables.scss
// https://element-plus.gitee.io/zh-CN/component/color.html
const colorMap = {
primary: {
base: '#409eff',
DEFAULT: '#409eff',
},
success: {
base: '#67c23a',
DEFAULT: '#67c23a',
},
warning: {
base: '#e6a23c',
DEFAULT: '#e6a23c',
},
danger: {
base: '#f56c6c',
DEFAULT: '#f56c6c',
},
info: {
base: '#909399',
DEFAULT: '#909399',
},
'primary-text': '#303133',
'regular-text': '#606266',
'secondary-text': '#909399',
'placeholder-text': '#c0c4cc',
'base-border': '#dcdfe6',
'light-border': '#e4e7ed',
'lighter-border': '#ebeef5',
'extra-light-border': '#f2f6fc',
bg: '#f5f7fa',
};
const types = ['primary', 'success', 'warning', 'danger', 'info'];
for (const type of types) {
for (let i = 1; i <= 9; i += 1) {
colorMap[type][`lighten-${i}`] = color(colorMap[type].base)
.mix(color('white'), i / 10)
.hex();
colorMap[type][`darken-${i}`] = color(colorMap[type].base)
.mix(color('black'), i / 10)
.hex();
}
}
module.exports = {
content: ['./index.html', './src/**/*.{vue,js,ts,jsx,tsx}'],
theme: {
extend: {
screens: {
sm: '576px',
md: '768px',
lg: '992px',
xl: '1200px',
'2xl': '1600px',
xxl: '1600px',
},
colors: {
...Object.fromEntries(Object.entries(colorMap).map(([key, value]) => [key, value])),
},
boxShadow: {
base: '0 2px 4px rgba(0, 0, 0, 0.12), 0 0 6px rgba(0, 0, 0, 0.04)',
light: '0 2px 12px 0 rgba(0, 0, 0, 0.1)',
},
},
},
plugins: [tailwindcssTypography, tailwindcssLineClamp, tailwindcssAspectRatio],
corePlugins: {
preflight: false,
},
};
{
"extends": "@vue/tsconfig/tsconfig.web.json",
"compilerOptions": {
"baseUrl": ".",
"jsx": "preserve",
"paths": {
"@/*": ["./src/*"]
},
"types": ["@dcloudio/types", "type-fest", "vite/client", "vue/macros-global"]
},
"exclude": [".cache", ".temp", ".tmp", "cache", "temp", "tmp", "dist*", "node_modules"]
}
import path from 'node:path';
// import { fileURLToPath } from 'url';
import uni from '@dcloudio/vite-plugin-uni';
import eslint from '@modyqyw/vite-plugin-eslint';
import tailwindcss from 'tailwindcss';
// @ts-ignore
import postcssPresetEnv from 'postcss-preset-env';
import { defineConfig } from 'vite';
import env from 'vite-plugin-env-compatible';
import stylelint from 'vite-plugin-stylelint';
import inspect from 'vite-plugin-inspect';
// https://vitejs.dev/config/
export default defineConfig({
build: {
target: 'es2015',
},
css: {
// FIX: not support postcss config file yet
postcss: {
plugins: [
tailwindcss(),
postcssPresetEnv({
stage: 3,
}),
],
},
preprocessorOptions: {
preprocessorOptions: {
scss: {
charset: false,
additionalData: `@use "@/styles/variables.scss" as *;`,
},
},
},
},
plugins: [
uni({
// FIX: nothing happened, must use UNI_OUTPUT_DIR
// outputDir: path.resolve(process.cwd(), 'dist', process.env.UNI_PLATFORM ?? 'h5'),
// https://github.com/dcloudio/uni-app/issues/3248
vueOptions: {
reactivityTransform: true,
},
viteLegacyOptions: {
targets: ['ios >= 10', 'chrome >= 53'],
},
}),
env({
prefix: 'VITE',
}),
eslint({
fix: true,
}),
stylelint({
fix: true,
}),
inspect(),
],
resolve: {
alias: {
// '@': fileURLToPath(new URL('./src', import.meta.url)),
'@/': `${path.resolve('src')}/`,
},
},
});
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment