Commit 5978ee25 by dengjianjie

feat: init

parents
# 检查代码质量、类型和测试
# 提交到主分支或 PR 到主分支时触发
trigger:
branches:
include:
- main
pr:
branches:
include:
- main
pool:
name: POOL_NAME_HERE
steps:
- checkout: self
fetchDepth: 1
displayName: Checkout
clean: true
- task: NodeTool@0
inputs:
versionSpec: 18.x
displayName: Install Node.js
- script: npm install --location=global --force corepack concurrently
displayName: Install Corepack & Concurrently
- script: corepack enable
displayName: Install PNPM
- script: pnpm install
displayName: Install Dependencies
- script: conc "pnpm:lint" "pnpm:check:types" "pnpm:test:unit"
displayName: Lint & Check Types & Test
module.exports = {
extends: ['@commitlint/config-conventional'],
};
{
"path": "@commitlint/prompt"
}
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')],
};
# 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
# Optional stylelint cache
.stylelintcache
# 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
.nitro
.output
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
module.exports = {
'package.json': 'sort-package-json',
'*.md': 'markdownlint --fix --ignore-path=.gitignore',
'*.{css,scss,vue}': 'stylelint --fix --cache --ignore-path=.gitignore',
'*.{js,cjs,mjs,jsx,ts,cts,mts,tsx,vue}': 'eslint --fix --cache --ignore-path=.gitignore',
'*.{ts,cts,mts,tsx,vue}': () => 'vue-tsc --noEmit -p tsconfig.vitest.json --composite false',
};
{
"MD001": false,
"MD003": false,
"MD013": false,
"MD022": false,
"MD024": false,
"MD025": false,
"MD033": false,
"MD036": false,
"MD050": false
}
shamefully-hoist=true
registry=https://registry.npmmirror.com
module.exports = {
...require('@modyqyw/fabric/prettier'),
};
module.exports = {
"pre-commit": "npx lint-staged",
"commit-msg": "npx commitlint --edit ${1}",
};
module.exports = {
extends: ['@modyqyw/fabric/stylelint'],
};
module.exports = {
scripts: {
prerelease: "pnpm install && conc \"pnpm:lint\" \"pnpm:check:types\" \"pnpm:test:unit\"",
posttag: "git push --follow-tags"
},
};
{
"recommendations": [
"russell.any-rule",
"streetsidesoftware.code-spell-checker",
"adam-bender.commit-message-editor",
"dotenv.dotenv-vscode",
"editorconfig.editorconfig",
"dbaeumer.vscode-eslint",
"mhutchie.git-graph",
"donjayamanne.githistory",
"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",
"stylelint.vscode-stylelint",
"jock.svg",
"antfu.unocss",
"gruntfuggly.todo-tree",
"redhat.vscode-yaml",
"Vue.volar"
],
// 这实际上不会起作用
// 参考 https://github.com/johnsoncodehk/volar/discussions/471
// 参考 https://github.com/microsoft/vscode/issues/40239
"disabled": ["vscode.typescript-language-features"]
}
{
"cSpell.language": "en,en-US",
"cSpell.enabledLanguageIds": [
"css",
"html",
"javascript",
"javascriptreact",
"json",
"jsonc",
"json5",
"markdown",
"plaintext",
"scss",
"text",
"typescript",
"typescriptreact",
"vue",
"yaml",
"yml"
],
"css.validate": false,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.guides.bracketPairs": true,
"editor.inlineSuggest.enabled": true,
"editor.tabSize": 2,
"editor.wordWrap": "on",
"eslint.validate": ["javascript", "javascriptreact", "typescript", "typescriptreact", "vue"],
"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",
"*.wpy": "vue",
"*.nvue": "vue",
"*.ux": "vue",
"manifest.json": "jsonc",
"pages.json": "jsonc",
"tsconfig.json": "jsonc",
"settings.json": "jsonc"
},
"git.autofetch": true,
"javascript.updateImportsOnFileMove.enabled": "always",
"scss.validate": false,
"search.exclude": {
"**/cache/**": true,
"**/.cache/**": true,
"**/temp/**": true,
"**/.temp/**": true,
"**/tmp/**": true,
"**/.tmp/**": true,
"**/dist/**": true,
"**/out/**": true,
"**/*lock*": true
},
"stylelint.snippet": ["css", "scss", "vue"],
"stylelint.validate": ["css", "scss", "vue"],
"typescript.updateImportsOnFileMove.enabled": "always",
"vue.codeActions.enabled": false,
"[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
}
},
"[scss]": {
"editor.codeActionsOnSave": {
"source.fixAll.stylelint": true
}
},
"[vue]": {
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit",
"source.fixAll.stylelint": "explicit"
}
},
"[markdown]": {
"editor.codeActionsOnSave": {
"source.fixAll.markdownlint": "explicit"
}
},
"[css][scss]": {
"editor.codeActionsOnSave": {
"source.fixAll.stylelint": "explicit"
}
},
"[javascript][javascriptreact][typescript][typescriptreact]": {
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
}
}
}
# uni-app
uni-app 模板,适用于小程序和移动端应用开发。
请使用 [Vue Language Features (Volar)](https://github.com/vuejs/language-tools)[接管模式 Takeover Mode](https://cn.vuejs.org/guide/typescript/overview.html#volar-takeover-mode)
## 特性
### UI
- [uni-ui](https://github.com/dcloudio/uni-ui)
- [unocss](https://unocss.dev) - 原子化 CSS
<details>
<summary> uni-ui 外的选择 </summary>
- [ano-ui](https://ano-ui.vercel.app)
- [nutui-uniapp](https://www.uniapp-nutui.tech/)
- [tm-ui](https://tmui.design/)
- [uview-plus](https://github.com/ijry/uview-plus)
- [uv-ui](https://github.com/climblee/uv-ui)
- [thor-ui](https://thorui.cn/doc/)
</details>
### 组合式
- [vue-use](https://vueuse.org/)
- [@uni-helper/uni-use](https://github.com/uni-helper/uni-use)
### 路由
- [@uni-helper/vite-plugin-uni-pages](https://github.com/uni-helper/vite-plugin-uni-pages)
### 状态管理
- [pinia](https://pinia.vuejs.org/)
### 请求
- [@uni-helper/uni-network](https://github.com/uni-helper/uni-network)
- [@tanstack/vue-query](https://tanstack.com/query)
### 其它插件
- [@vitejs/plugin-vue](https://github.com/vitejs/vite/tree/main/packages/plugin-vue)
- [@vitejs/plugin-vue-jsx](https://github.com/vitejs/vite/tree/main/packages/plugin-vue-jsx)
- [@vitejs/plugin-legacy](https://github.com/vitejs/vite/tree/main/packages/plugin-legacy)
- [@dcloudio/vite-plugin-uni](https://www.npmjs.com/package/@dcloudio/vite-plugin-uni/)
- [unplugin-auto-import](https://github.com/antfu/unplugin-auto-import)
- [unplugin-icons](https://github.com/antfu/unplugin-icons)
- [@uni-helper/vite-plugin-uni-components](https://github.com/uni-helper/vite-plugin-uni-components)
- [@uni-helper/vite-plugin-uni-layouts](https://github.com/uni-helper/vite-plugin-uni-layouts)
- [@uni-helper/vite-plugin-uni-manifest](https://github.com/uni-helper/vite-plugin-uni-manifest)
- [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version)
/* eslint-disable */
/* prettier-ignore */
// @ts-nocheck
// Generated by vite-plugin-uni-components
// Read more: https://github.com/vuejs/core/pull/3399
import '@vue/runtime-core'
export {}
declare module '@vue/runtime-core' {
export interface GlobalComponents {
VSpacer: typeof import('./src/components/v-spacer/v-spacer.vue')['default']
}
}
<!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" />
<meta
name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"
/>
<link rel="icon" href="/favicon.ico" />
<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>uni-app</title>
<!--preload-links-->
<!--app-context-->
</head>
<body>
<noscript>
<strong>请允许 JavaScript 执行。</strong>
</noscript>
<div id="app" class="relative">
<style>
body {
margin: 0;
}
@keyframes spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
</style>
<div style="display: flex; justify-content: center; padding: 5rem">
<svg
xmlns="http://www.w3.org/2000/svg"
width="1em"
height="1em"
viewBox="0 0 1024 1024"
style="font-size: 2.25rem; line-height: 2.5rem; animation: spin 1s linear infinite"
>
<path
fill="currentColor"
d="M512 64a32 32 0 0 1 32 32v192a32 32 0 0 1-64 0V96a32 32 0 0 1 32-32zm0 640a32 32 0 0 1 32 32v192a32 32 0 1 1-64 0V736a32 32 0 0 1 32-32zm448-192a32 32 0 0 1-32 32H736a32 32 0 1 1 0-64h192a32 32 0 0 1 32 32zm-640 0a32 32 0 0 1-32 32H96a32 32 0 0 1 0-64h192a32 32 0 0 1 32 32zM195.2 195.2a32 32 0 0 1 45.248 0L376.32 331.008a32 32 0 0 1-45.248 45.248L195.2 240.448a32 32 0 0 1 0-45.248zm452.544 452.544a32 32 0 0 1 45.248 0L828.8 783.552a32 32 0 0 1-45.248 45.248L647.744 692.992a32 32 0 0 1 0-45.248zM828.8 195.264a32 32 0 0 1 0 45.184L692.992 376.32a32 32 0 0 1-45.248-45.248l135.808-135.808a32 32 0 0 1 45.248 0zm-452.544 452.48a32 32 0 0 1 0 45.248L240.448 828.8a32 32 0 0 1-45.248-45.248l135.808-135.808a32 32 0 0 1 45.248 0z"
/>
</svg>
</div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>
import { defineManifestConfig } from '@uni-helper/vite-plugin-uni-manifest';
import shell from 'shelljs';
import { name, description, version } from './package.json';
const shellResult = shell.exec('git tag | wc -l', { silent: true });
const versionCode = shellResult.code === 0 ? Number.parseInt(shellResult.stdout.trim(), 10) : 0;
export default defineManifestConfig({
name,
appid: '',
description,
versionName: version,
versionCode: versionCode.toString(),
transformPx: false,
networkTimeout: {
request: 60_000,
connectSocket: 600_000,
uploadFile: 60_000,
downloadFile: 60_000,
},
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',
},
screenOrientation: ['portrait-primary'],
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: {},
// @ts-expect-error type lost
splashscreen: {
useOriginalMsgbox: true,
},
sdkConfigs: {
ad: {},
},
},
},
h5: {},
'mp-weixin': {
appid: 'touristappid',
usingComponents: true,
libVersion: '2.16.1',
permission: {},
setting: {
es6: false,
enhance: false,
// @ts-expect-error type lost
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: version,
versionCode,
},
'quickapp-webview-union': {
minPlatformVersion: 1063,
},
'quickapp-webview-huawei': {
minPlatformVersion: 1070,
},
vueVersion: '3',
});
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed. Click to expand it.
import { defineUniPages } from '@uni-helper/vite-plugin-uni-pages';
export default defineUniPages({
globalStyle: {
navigationBarTextStyle: 'black',
navigationBarTitleText: 'uni-app',
navigationBarBackgroundColor: '#F8F8F8',
backgroundColor: '#F8F8F8',
},
});
This source diff could not be displayed because it is too large. You can view the blob instead.
<script setup lang="ts">
import { focusManager, onlineManager } from '@tanstack/vue-query';
onLaunch(() => {
console.log('App Launch');
});
onShow(() => {
console.log('App Show');
});
onHide(() => {
console.log('App Hide');
});
const isOnline = useOnline();
watchEffect(() => {
onlineManager.setOnline(isOnline.value);
});
onShow(() => {
focusManager.setFocused(true);
});
onHide(() => {
focusManager.setFocused(false);
});
</script>
{
"$schema": "https://raw.githubusercontent.com/uni-helper/uni-app-schemas-vscode/main/schemas/androidPrivacy.json",
"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"
}
}
import VSpacer from './v-spacer.vue';
export type VSpacerInstance = InstanceType<typeof VSpacer>;
export { default as VSpacer } from './v-spacer.vue';
<script setup lang="ts">
/** 分隔组件 */
defineOptions({
name: 'VSpacer',
});
</script>
<template>
<div class="flex-auto" />
</template>
export * from './usePagination';
export * from './useTheme';
export * from './useToken';
import { useStorageAsync } from '@uni-helper/uni-use';
import { DefaultPageSize, PageSizeKey, DefaultPageSizes } from '@/constants';
export const usePagination = (
initialCurrentPage = 1,
initialPageSize = DefaultPageSize,
initialTotal = 0,
) => {
const currentPage = ref(initialCurrentPage);
const pageSize = useStorageAsync(PageSizeKey, initialPageSize);
const total = ref(initialTotal);
watch(pageSize, () => {
currentPage.value = 1;
});
return {
currentPage,
page: currentPage,
pageSize,
pageSizes: DefaultPageSizes,
total,
};
};
import { useStorageAsync } from '@uni-helper/uni-use';
import { ThemeKey } from '@/constants';
export const useTheme = () => {
const theme = useStorageAsync<'auto' | 'light' | 'dark'>(ThemeKey, 'auto');
const parsedTheme = computed(() => {
if (theme.value !== 'auto') return theme.value;
return usePreferredDark().value ? 'dark' : 'light';
});
const toggleTheme = () => {
if (theme.value === 'auto') {
theme.value = 'light';
return;
}
if (theme.value === 'light') {
theme.value = 'dark';
return;
}
theme.value = 'auto';
return;
};
return { theme, parsedTheme, toggleTheme };
};
import { useStorageAsync } from '@uni-helper/uni-use';
import { TokenKey, DefaultToken } from '@/constants';
export const useToken = (initialToken = DefaultToken) => {
const token = useStorageAsync(TokenKey, initialToken);
return token;
};
import { pascalCase } from 'change-case';
import pkg from '@/../package.json';
const ViteMode = import.meta.env.VITE_MODE || 'production';
const PascalCaseViteMode = pascalCase(ViteMode);
export { default as pkg } from '@/../package.json';
// 请求
/** 默认请求基地址 */
export const DefaultBaseUrl =
import.meta.env.VITE_REQUEST_BASE_URL || 'https://jsonplaceholder.typicode.com/';
/** 默认请求头 */
export const DefaultHeaders = {
Accept: 'application/json',
'Content-Type': 'application/json; charset=utf-8',
'X-Version': `${pkg.name}/${pkg.version}`,
};
/** 登录态键 */
export const TokenKey = `token${PascalCaseViteMode}`;
/** 默认登录态 */
export const DefaultToken = '';
// 通用
/** 每页条目键 */
export const PageSizeKey = `pageSize${PascalCaseViteMode}`;
/** 默认每页条目 */
export const DefaultPageSize = 10;
/** 默认可选每页条目 */
export const DefaultPageSizes = [10, 20, 50, 100];
export const ThemeKey = `theme${PascalCaseViteMode}`;
export const showActionSheet = (options: UniApp.ShowActionSheetOptions) =>
uni.showActionSheet({
...options,
});
export * from './action-sheet';
export * from './loading';
export * from './modal';
export * from './network';
export * from './toast';
export * from './updater';
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: '提示',
showCancel: false,
...options,
});
import { reactive } from 'vue';
import un from '@uni-helper/uni-network';
import qs from 'qs';
import { QueryClient, QueryCache, MutationCache } from '@tanstack/vue-query';
import type { VueQueryPluginOptions } from '@tanstack/vue-query';
import { showModal } from './modal';
import { showToast } from './toast';
import { useAuthStore } from '@/stores';
import { DefaultBaseUrl, DefaultHeaders } from '@/constants';
const reSignInCodes = new Set(['LOGIN_REQUIRED', 'LOGIN_TOKEN_INVALID', 'LOGIN_SESSION_EXPIRED']);
const instance = un.create({
baseUrl: DefaultBaseUrl,
timeout: 30_000,
paramsSerializer: (params: any) =>
qs.stringify(
Object.fromEntries(
Object.entries(params).filter(
([, v]) => !['undefined', 'null', undefined, null].includes((v as any)?.toString() ?? v),
),
),
),
});
export { instance as unInstance };
let hasModal = false;
export const showNetworkError = ({
hasPrefix = true,
message,
response,
error,
type = 'modal' as IUnShowErrorType,
success,
fail,
complete,
}:
| {
hasPrefix?: boolean;
message?: string;
response?: IUnResponse;
error?: IUnError;
type?: 'modal';
success?: UniApp.ShowModalOptions['success'];
fail?: UniApp.ShowModalOptions['fail'];
complete?: UniApp.ShowModalOptions['complete'];
}
| {
hasPrefix?: boolean;
message?: string;
response?: IUnResponse;
error?: IUnError;
type: 'toast';
success?: UniApp.ShowToastOptions['success'];
fail?: UniApp.ShowToastOptions['fail'];
complete?: UniApp.ShowToastOptions['complete'];
} = {}) => {
// method
const method =
error?.config?.method ??
error?.task?.method ??
// @ts-expect-error no types
error?.method ??
response?.config?.method ??
response?.task?.method ??
// @ts-expect-error no types
response?.method ??
'';
const methodText = method ? `请求方法:${method}` : '';
// url
const url =
error?.config?.url ??
error?.task?.url ??
// @ts-expect-error no types
error?.url ??
response?.config?.url ??
response?.task?.url ??
// @ts-expect-error no types
response?.url ??
'';
const urlText = url ? `请求地址:${url}` : '';
// statusCode
const statusCode =
error?.status ??
// @ts-expect-error no types
error?.statusCode ??
// @ts-expect-error no types
error?.data?.status ??
// @ts-expect-error no types
error?.data?.statusCode ??
response?.status ??
// @ts-expect-error no types
response?.statusCode ??
response?.data?.status ??
response?.data?.statusCode ??
0;
const statusCodeText = statusCode ? `状态代码:${statusCode}` : '';
// errorCode
const errorCode =
error?.code ??
// @ts-expect-error no types
error?.errno ??
// @ts-expect-error no types
error?.data?.code ??
// @ts-expect-error no types
error?.data?.errno ??
// @ts-expect-error no types
response?.code ??
response?.errno ??
response?.data?.code ??
response?.data?.errno ??
'';
const errorCodeText = errorCode ? `错误代码:${errorCode}` : '';
// errorMessage
const errorMessage =
// @ts-expect-error no types
error?.data?.errMsg ??
// @ts-expect-error no types
error?.data?.message ??
// @ts-expect-error no types
error?.data?.msg ??
// @ts-expect-error no types
error?.errMsg ??
error?.message ??
// @ts-expect-error no types
error?.msg ??
response?.data?.errMsg ??
response?.data?.message ??
response?.data?.msg ??
response?.errMsg ??
// @ts-expect-error no types
response?.message ??
// @ts-expect-error no types
response?.msg ??
message ??
'';
const errorMessageText = errorMessage ? `错误信息:${errorMessage}` : '';
const content = `${[
hasPrefix ? '发生了错误。' : '',
errorMessageText,
errorCodeText,
methodText,
urlText,
statusCodeText,
]
.filter((item) => !!item)
.join('\r\n')}`;
if (type === 'toast') {
showToast({
title: content,
success,
fail,
complete,
});
return;
}
if (type === 'modal' && !hasModal) {
hasModal = true;
showModal({
title: '错误',
content,
success: (result) => {
success?.(result);
hasModal = false;
},
fail: (result) => {
fail?.(result);
hasModal = false;
},
complete,
});
}
};
export const vueQueryClient = new QueryClient({
queryCache: new QueryCache({
onError: (error) => {
if (un.isCancel(error)) return;
showNetworkError({ error: error as IUnError });
},
}),
mutationCache: new MutationCache({
onError: (error) => {
if (un.isCancel(error)) return;
showNetworkError({ error: error as IUnError });
},
}),
defaultOptions: {
queries: {
queryFn: async (context) => {
const authStore = useAuthStore();
const queryKey = reactive({ ...context.queryKey });
const url = queryKey[0] as string;
const config = reactive({ ...(queryKey[1] as IUnConfig) });
const response = await instance.request<IUnResponseData, IUnRequestData, IUnResponse>({
method: 'GET',
url,
...config,
headers: {
...DefaultHeaders,
token: authStore.token,
'X-Token': authStore.token,
'X-Access-Token': authStore.token,
...config.headers,
},
});
if (!(response?.data?.success ?? false)) {
if (reSignInCodes.has(response?.data?.code ?? '')) {
authStore.setToken();
showNetworkError({
hasPrefix: false,
message: '请重新登录。',
});
uni.reLaunch({
url: '/pages/index',
});
} else if (config?.showError ?? true) {
showNetworkError({
response,
error: response?.data as unknown as IUnError,
type: config?.showErrorType,
});
}
}
return response?.data;
},
retry: 1,
refetchOnWindowFocus: import.meta.env.PROD,
},
mutations: {
mutationFn: async (variables) => {
const authStore = useAuthStore();
const config = reactive({ ...(variables as IUnConfig) });
const response = await instance.request<IUnResponseData, IUnRequestData, IUnResponse>({
method: 'POST',
...config,
headers: {
...DefaultHeaders,
token: authStore.token,
'X-Token': authStore.token,
'X-Access-Token': authStore.token,
...config.headers,
},
});
if (!(response?.data?.success ?? false)) {
if (reSignInCodes.has(response?.data?.code ?? '')) {
authStore.setToken();
showNetworkError({
hasPrefix: false,
message: '请重新登录。',
});
uni.reLaunch({
url: '/pages/index',
});
} else if (config?.showError ?? true) {
showNetworkError({
response,
error: response?.data as unknown as IUnError,
type: config?.showErrorType,
});
}
}
return response?.data;
},
},
},
});
export const vueQueryPluginOptions: VueQueryPluginOptions = {
queryClient: vueQueryClient,
};
export const showToast = (options: UniApp.ShowToastOptions) =>
uni.showToast({
...options,
});
export const hideToast = () => uni.hideToast();
// 小程序更新见 https://uniapp.dcloud.io/api/other/update?id=getupdatemanager
// 整包更新见 https://ask.dcloud.net.cn/article/34972
// 热更新见 https://ask.dcloud.net.cn/article/35667
import manifest from '../manifest.json';
import { hideLoading, showLoading } from './loading';
import { showModal } from './modal';
import { unInstance } from './network';
/* #ifdef APP-PLUS */
const removeInstalledResources = () => {
plus.io.requestFileSystem(plus.io.PUBLIC_DOWNLOADS, (fs) => {
const directoryReader = fs.root?.createReader();
if (directoryReader) {
// @ts-expect-error wrong types
directoryReader.readEntries((entries: (PlusIoDirectoryEntry | PlusIoFileEntry)[]) => {
const apkFiles = entries.filter(
(entry) =>
entry?.isFile &&
(entry?.name?.toUpperCase()?.endsWith('.APK') ||
entry?.name?.toUpperCase()?.endsWith('.WGT') ||
entry?.name?.toUpperCase()?.endsWith('.WGTU')) &&
entry?.name?.toUpperCase()?.includes('ECARD'),
) as PlusIoFileEntry[];
for (const apkFile of apkFiles) apkFile.remove();
});
}
});
};
/* #endif */
export const getUpdate = ({ hasLoading = false } = {}) => {
/* #ifdef MP */
const updater = uni.getUpdateManager();
updater.onCheckForUpdate(({ hasUpdate }) => {
if (!hasUpdate) {
if (hasLoading) {
showModal({
content: '已经是最新版本。',
});
}
return;
}
updater.onUpdateReady(() => {
showModal({
content: '新版本应用已经准备完毕,请重启应用。',
success: ({ confirm }) => {
if (confirm) {
updater.applyUpdate();
}
},
});
});
});
/* #endif */
/* #ifdef APP-PLUS */
removeInstalledResources();
if (hasLoading) {
showLoading({
title: '更新中,请稍候',
});
}
const { platform } = uni.getSystemInfoSync();
plus.runtime.getProperty(plus.runtime.appid || '', (widgetInfo) => {
unInstance<IUnResponseData, IUnRequestData>({
// TODO 补充链接
url: '',
data: {
platform,
app_id:
widgetInfo.appid && widgetInfo.appid.includes('HBuilder')
? manifest.appid
: widgetInfo.appid,
version: widgetInfo.version,
},
}).then((response) => {
if (response.data?.success) {
// 请求成功
if (response.data?.update) {
// 有更新
if (response.data?.hot_url) {
// 热更新
uni.downloadFile({
url: response.data.hot_url,
success: ({ tempFilePath, statusCode }) => {
if (statusCode >= 200 && statusCode < 300) {
plus.runtime.install(
tempFilePath,
{ force: false },
() => {
if (hasLoading) {
hideLoading();
}
showModal({
content: `新版本应用 ${response.data?.version} 已经准备完毕,请重启应用。${
response.data?.note ? `\r\n更新信息:${response.data.note}` : ''
}`,
success: ({ confirm }) => {
if (confirm) {
plus.runtime.restart();
}
},
});
},
() => {
if (hasLoading) {
hideLoading();
showModal({
content: `新版本应用 ${response.data?.version} 安装失败,请稍候再试。`,
});
}
},
);
}
},
});
} else if (platform === 'ios') {
// iOS 整包更新需要打开 AppStore 引导用户更新
// TODO 补充链接
// plus.runtime.openURL();
} else {
// Android 整包更新可直接获取并安装
uni.downloadFile({
url: response.data.pkg_url,
success: ({ tempFilePath, statusCode }) => {
if (statusCode >= 200 && statusCode < 300) {
if (hasLoading) {
hideLoading();
}
showModal({
content: `新版本应用 ${response.data?.version} 已经下载完毕,请安装更新应用。${
response.data?.note ? `\r\n更新信息:${response.data?.note}` : ''
}`,
success: ({ confirm }) => {
if (confirm) {
plus.runtime.install(tempFilePath, { force: true });
}
},
});
}
},
});
}
} else if (hasLoading) {
// 没有更新
hideLoading();
showModal({
content: '已经是最新版本。',
});
}
} else if (hasLoading) {
// 请求失败
hideLoading();
showModal({
content: `无法检查更新,是否重试?`,
showCancel: true,
success: ({ confirm }) => {
if (confirm) {
getUpdate();
}
},
});
}
});
});
/* #endif */
};
<template>
<slot></slot>
</template>
// check https://wechat-miniprogram.github.io/miniprogram-compat/
// import 'core-js/actual';
import 'core-js/actual/structured-clone';
// import 'core-js/actual/array/flat'; // since 2.16.1
// import 'core-js/actual/array/flat-map'; // since 2.16.1
// import 'core-js/actual/object/entries'; // since 2.16.1
// import 'core-js/actual/object/from-entries'; // since 2.16.1
// import 'core-js/actual/object/values'; // since 2.16.1
// import 'core-js/actual/promise'; // since 2.11.0
// import 'core-js/actual/promise/all-settled'; // since 2.16.1
// import 'core-js/actual/promise/finally'; // since 2.16.1
// import 'core-js/actual/string/pad-end'; // since 2.16.1
// import 'core-js/actual/string/pad-start'; // since 2.16.1
import 'core-js/actual/string/replace-all'; // since 2.16.1 but consider other platforms
// import 'core-js/actual/string/trim-end'; // since 2.16.1
// import 'core-js/actual/string/trim-start'; // since 2.16.1
import { createSSRApp } from 'vue';
import { pinia } from './stores';
import App from './App.vue';
import { dayjsPlugin, vueQueryPlugin } from './plugins';
import './styles/button-preflight.css';
import '@unocss-applet/reset/uni-app/tailwind-compat.css';
import './styles/preflight.css';
import './styles/global.scss';
import 'virtual:uno.css';
export function createApp() {
const app = createSSRApp(App).use(pinia).use(dayjsPlugin).use(vueQueryPlugin);
return { app };
}
{
"name": "uni-app",
"appid": "wx56bfae4c7dd61091",
"description": "A boilerplate for uni-app (vue3).",
"versionName": "0.0.0",
"versionCode": "0",
"transformPx": false,
"app-plus": {
"usingComponents": true,
"nvueStyleCompiler": "uni-app",
"compilerVersion": 3,
"splashscreen": {
"alwaysShowBeforeRender": true,
"waiting": true,
"autoclose": true,
"delay": 0
},
"modules": {},
"distribute": {
"android": {
"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\"/>"
],
"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": "为保证正常安全使用,需要获取设备识别码使用权限,系统可能提示为获取手机号码,请允许。"
}
},
"ios": {},
"sdkConfigs": { "ad": {} },
"splashscreen": { "useOriginalMsgbox": true }
},
"compatible": { "ignoreVersion": true },
"nvueCompiler": "uni-app",
"nvueLaunchMode": "normal",
"nvue": { "flex-direction": "column" },
"screenOrientation": ["portrait-primary"]
},
"quickapp": {},
"mp-weixin": {
"appid": "touristappid",
"setting": {
"urlCheck": true,
"es6": false,
"enhance": false,
"nodeModules": false,
"postcss": false,
"minifyWXSS": false,
"minified": false,
"uglifyFileName": false,
"showShadowRootInWxmlPanel": true,
"preloadBackgroundData": false,
"compileHotReLoad": false,
"bundle": false,
"checkSiteMap": false,
"checkInvalidKey": false
},
"usingComponents": true,
"libVersion": "2.16.1",
"permission": {}
},
"mp-alipay": {
"usingComponents": true,
"component2": true,
"axmlStrictCheck": false,
"enableParallelLoader": true,
"enableAppxNg": true
},
"mp-baidu": { "usingComponents": true, "appid": "", "setting": { "urlCheck": true } },
"mp-toutiao": {
"usingComponents": true,
"appid": "",
"permission": {},
"setting": { "es6": false, "minified": false, "urlCheck": true }
},
"uniStatistics": { "enable": false },
"vueVersion": "3",
"networkTimeout": {
"request": 60000,
"connectSocket": 600000,
"uploadFile": 60000,
"downloadFile": 60000
},
"debug": false,
"h5": {},
"mp-qq": { "appid": "", "usingComponents": true, "permission": {} },
"quickapp-webview": {
"icon": "/static/logo.png",
"package": "cn.millcloud",
"versionName": "0.0.0",
"versionCode": 0
},
"quickapp-webview-union": { "minPlatformVersion": 1063 },
"quickapp-webview-huawei": { "minPlatformVersion": 1070 }
}
{"globalStyle":{"navigationBarTextStyle":"black","navigationBarTitleText":"uni-app","navigationBarBackgroundColor":"#F8F8F8","backgroundColor":"#F8F8F8"},"pages":[{"path":"pages/index/index","type":"home"}],"subPackages":[]}
\ No newline at end of file
<script setup lang="ts">
import { useQuery } from '@tanstack/vue-query';
import { useTheme } from '@/composables';
const title = ref('Hello World');
const id = ref(1);
const { data, isLoading } = useQuery<IUnResponseData, IUnRequestData>({
queryKey: [computed(() => `/posts/${id.value}`)],
});
const { theme, parsedTheme, toggleTheme } = useTheme();
</script>
<template>
<view class="items-center justify-center">
<image class="m-4 mx-auto block h-20 w-20" src="/static/logo.png" />
<view class="w-full flex items-center justify-center text-xl">
<view class="i-logos-vue"></view>
<text>{{ title }}</text>
</view>
<nut-cell>
<nut-button type="primary" class="mx-auto" @click="toggleTheme">
Theme: {{ theme }}, ParsedTheme: {{ parsedTheme }}
</nut-button>
</nut-cell>
<view class="w-full flex justify-center p-4">
<template v-if="isLoading">Loading...</template>
<template v-else>{{ data }}</template>
</view>
</view>
</template>
import dayjs from 'dayjs';
import customParseFormat from 'dayjs/plugin/customParseFormat';
import type { Plugin } from 'vue';
export const dayjsPlugin: Plugin = {
install: () => {
dayjs.extend(customParseFormat);
},
};
export * from './dayjs';
export * from './vue-query';
import { VueQueryPlugin } from '@tanstack/vue-query';
import type { Plugin } from 'vue';
import { vueQueryPluginOptions } from '@/helpers';
export const vueQueryPlugin: Plugin = {
install: (app) => {
app.use(VueQueryPlugin, vueQueryPluginOptions);
},
};
import { useToken } from '@/composables';
import { DefaultToken } from '@/constants';
export const useAuthStore = defineStore('auth', () => {
const token = useToken();
const setToken = (newToken = DefaultToken) => {
token.value = newToken;
};
return {
token,
setToken,
};
});
export const useCounterStore = defineStore('counter', () => {
const counter = ref(0);
const doubleCounter = computed(() => counter.value * 2);
const increase = () => {
counter.value += 1;
};
return { counter, doubleCounter, increase };
});
import { createPinia } from 'pinia';
export const pinia = createPinia();
export * from './auth';
export * from './counter';
button,
button::after {
all: unset;
}
button {
box-sizing: border-box;
-webkit-tap-highlight-color: transparent;
}
// global styles
html,
page {
font-size: var(--font-size, 16px) !important;
}
/*
* 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, 0.4); // 遮罩颜色
// 边框颜色
$uni-border-color: #c8c7cc;
/* 尺寸变量 */
// 文字尺寸
$uni-font-size-sm: 12px;
$uni-font-size-base: 14px;
$uni-font-size-lg: 16px;
// 图片尺寸
$uni-img-size-sm: 20px;
$uni-img-size-base: 26px;
$uni-img-size-lg: 40px;
/* 边框圆角 */
$uni-border-radius-sm: 2px;
$uni-border-radius-base: 3px;
$uni-border-radius-lg: 6px;
$uni-border-radius-circle: 50%;
/** 间距变量 */
// 水平间距
$uni-spacing-row-sm: 5px;
$uni-spacing-row-base: 10px;
$uni-spacing-row-lg: 15px;
// 垂直间距
$uni-spacing-col-sm: 4px;
$uni-spacing-col-base: 8px;
$uni-spacing-col-lg: 12px;
/* 透明度 */
$uni-opacity-disabled: 0.3; // 组件禁用态的透明度
/* 文章场景相关 */
$uni-color-title: #2c405a; // 文章标题颜色
$uni-font-size-title: 20px;
$uni-color-subtitle: #555; // 二级标题颜色
$uni-font-size-subtitle: 18px;
$uni-color-paragraph: #3f536e; // 文章段落颜色
$uni-font-size-paragraph: 15px;
export * from './uni-network';
import type { UnError, UnResponse, UnConfig } from '@uni-helper/uni-network';
type IUnShowErrorType_ = 'toast' | 'modal';
type IUnRequestData_ = Record<string, any>;
interface IUnResponseData_ {
success: boolean;
code: string;
message: string;
[key: string]: any;
}
interface IUnConfig_<T = IUnResponseData_, D = IUnRequestData_> extends UnConfig<T, D> {
showError?: boolean;
showErrorType?: IUnShowErrorType_;
}
interface IUnResponse_<T = IUnResponseData_, D = IUnRequestData_> extends UnResponse<T, D> {}
type IUnPromise_<T = IUnResponseData_, D = IUnRequestData_> = Promise<IUnResponse_<T, D>>;
interface IUnError_<T = IUnResponseData_, D = IUnRequestData_> extends UnError<T, D> {
response?: IUnResponse_<T, D>;
}
export type {
IUnShowErrorType_ as IUnShowErrorType,
IUnRequestData_ as IUnRequestData,
IUnResponseData_ as IUnResponseData,
IUnConfig_ as IUnConfig,
IUnResponse_ as IUnResponse,
IUnPromise_ as IUnPromise,
IUnError_ as IUnError,
};
declare global {
type IUnShowErrorType = IUnShowErrorType_;
interface IUnRequestData extends IUnRequestData_ {}
interface IUnResponseData extends IUnResponseData_ {}
interface IUnConfig<T = IUnResponseData_, D = IUnRequestData_> extends IUnConfig_<T, D> {}
interface IUnResponse<T = IUnResponseData_, D = IUnRequestData_> extends IUnResponse_<T, D> {}
type IUnPromise<T = IUnResponseData_, D = IUnRequestData_> = IUnPromise_<T, D>;
interface IUnError<T = IUnResponseData_, D = IUnRequestData_> extends IUnError_<T, D> {}
}
{
"extends": "@vue/tsconfig/tsconfig.dom.json",
"include": ["src/**/*", "src/**/*.json", "src/**/*.vue", "*.d.ts", "package.json"],
"exclude": ["src/**/__tests__/*", "src/**/*.test.*"],
"compilerOptions": {
"composite": true,
"baseUrl": ".",
"lib": ["ESNext"],
"paths": {
"@/*": ["./src/*"]
},
"types": [
"@dcloudio/types",
"@mini-types/alipay",
"miniprogram-api-typings",
"@uni-helper/uni-app-types",
"@uni-helper/uni-cloud-types",
"@uni-helper/uni-ui-types",
"unplugin-icons/types/vue",
"unplugin-vue-macros/macros-global",
"@vue-macros/volar/define-options",
"@vue-macros/volar/define-slots",
"type-fest",
"vite/client"
]
},
"vueCompilerOptions": {
"nativeTags": ["block", "component", "template", "slot"]
}
}
{
"files": [],
"references": [
{
"path": "./tsconfig.node.json"
},
{
"path": "./tsconfig.app.json"
},
{
"path": "./tsconfig.vitest.json"
}
]
}
{
"extends": "@tsconfig/node18/tsconfig.json",
"include": ["*.config.*", "*.conf.*", "scripts/**", "package.json"],
"compilerOptions": {
"composite": true,
"module": "ESNext",
"moduleResolution": "Bundler",
"types": ["node"]
}
}
{
"extends": "./tsconfig.app.json",
"exclude": [],
"compilerOptions": {
"composite": true,
"lib": ["ESNext"],
"types": [
"node",
"jsdom",
"@dcloudio/types",
"@mini-types/alipay",
"miniprogram-api-typings",
"@uni-helper/uni-app-types",
"@uni-helper/uni-cloud-types",
"@uni-helper/uni-ui-types",
"unplugin-icons/types/vue",
"type-fest",
"vite/client"
]
}
}
/* eslint-disable */
/* prettier-ignore */
// @ts-nocheck
// Generated by vite-plugin-uni-pages
interface NavigateToOptions {
url: "pages/index/index";
}
interface RedirectToOptions extends NavigateToOptions {}
interface SwitchTabOptions {
}
type ReLaunchOptions = NavigateToOptions | SwitchTabOptions;
declare interface Uni {
navigateTo(options: UniNamespace.NavigateToOptions & NavigateToOptions): void;
redirectTo(options: UniNamespace.RedirectToOptions & RedirectToOptions): void;
switchTab(options: UniNamespace.SwitchTabOptions & SwitchTabOptions): void;
reLaunch(options: UniNamespace.ReLaunchOptions & ReLaunchOptions): void;
}
import {
defineConfig,
presetIcons,
presetTypography,
presetWebFonts,
transformerDirectives,
transformerVariantGroup,
type Preset,
type SourceCodeTransformer,
} from 'unocss';
import presetRemToPx from '@unocss/preset-rem-to-px';
import { presetUni } from '@uni-helper/unocss-preset-uni';
// import { presetAntd } from 'unocss-preset-antd';
// import { presetElementPlus } from 'unocss-preset-element-plus';
// import { presetNaiveUi } from 'unocss-preset-naive-ui';
import { isMp } from '@uni-helper/uni-env';
const presets: Preset[] = [
presetUni({ remRpx: false }),
presetIcons(),
presetTypography(),
presetWebFonts(),
// presetAntd(),
// presetElementPlus({
// preferCssVariables: false,
// selectors: {
// light: ':root,page,.root,page',
// dark: '.dark,.root.dark',
// },
// }),
// presetNaiveUi({
// preferCssVariables: false,
// selectors: {
// light: ':root,page,.root,page',
// dark: '.dark,.root.dark',
// },
// }),
];
if (isMp) {
presets.push(presetRemToPx());
}
const transformers: SourceCodeTransformer[] = [transformerDirectives(), transformerVariantGroup()];
const config = defineConfig({
presets,
transformers,
});
export default config;
import { fileURLToPath } from 'node:url';
import { defineConfig } from 'vitest/config';
import postcssPresetEnv from 'postcss-preset-env';
import uniManifest from '@uni-helper/vite-plugin-uni-manifest';
import uniPages from '@uni-helper/vite-plugin-uni-pages';
import uniLayouts from '@uni-helper/vite-plugin-uni-layouts';
import autoImport from 'unplugin-auto-import/vite';
import { UniUseAutoImports } from '@uni-helper/uni-use';
import uniComponents from '@uni-helper/vite-plugin-uni-components';
import { UniUIResolver } from '@uni-helper/vite-plugin-uni-components/resolvers';
import unocss from 'unocss/vite';
import IconsResolver from 'unplugin-icons/resolver';
import icons from 'unplugin-icons/vite';
import vueMacros from 'unplugin-vue-macros/vite';
import uni from '@dcloudio/vite-plugin-uni';
// https://vitejs.dev/config/
export default defineConfig({
build: {
target: 'es6',
cssTarget: 'chrome61',
},
css: {
postcss: {
plugins: [postcssPresetEnv()],
},
preprocessorOptions: {
scss: {
charset: false,
additionalData: `@import '@/styles/variables.scss';`,
},
},
},
envPrefix: ['VITE_', 'UNI_'],
optimizeDeps: {
exclude: ['vue-demi'],
},
plugins: [
uniManifest({ minify: true }),
uniPages({ minify: true }),
uniLayouts(),
autoImport({
dirs: ['helpers', 'composables', 'constants', 'helpers', 'stores', 'utils'].map(
(item) => `src/${item}/**`,
),
imports: ['vue', 'pinia', 'uni-app', '@vueuse/core', UniUseAutoImports],
vueTemplate: true,
}),
uniComponents({
resolvers: [IconsResolver(), UniUIResolver()],
directoryAsNamespace: true,
collapseSamePrefixes: true,
}),
unocss(),
icons({
compiler: 'vue3',
}),
vueMacros(),
uni({
vueOptions: {},
vueJsxOptions: {},
viteLegacyOptions: {
targets: ['ios >= 10', 'chrome >= 53'],
polyfills: true,
modernPolyfills: true,
},
}),
],
resolve: {
alias: {
'@': fileURLToPath(new URL('src', import.meta.url)),
},
},
});
import { fileURLToPath } from 'node:url';
import { mergeConfig, defineConfig, configDefaults } from 'vitest/config';
import viteConfig from './vite.config';
export default mergeConfig(
viteConfig,
defineConfig({
test: {
environment: 'jsdom',
exclude: [...configDefaults.exclude, 'e2e/*'],
root: fileURLToPath(new URL('./', import.meta.url)),
singleThread: true,
},
}),
);
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