feat: 大量升级,v2.0.0

This commit is contained in:
菲鸽 2024-04-17 15:32:15 +08:00
parent 09fbee72aa
commit 28caa1dea3
37 changed files with 233 additions and 297 deletions

View File

@ -86,6 +86,7 @@
"watch": true, "watch": true,
"watchEffect": true, "watchEffect": true,
"watchPostEffect": true, "watchPostEffect": true,
"watchSyncEffect": true "watchSyncEffect": true,
"useRequest": true
} }
} }

View File

@ -4,7 +4,8 @@ module.exports = {
root: true, root: true,
extends: [ extends: [
'stylelint-config-standard', 'stylelint-config-standard',
'stylelint-config-standard-scss', // tips: 本插件也可以替换成 stylelint-config-recommended-scss // stylelint-config-standard-scss 替换成了更宽松的 stylelint-config-recommended-scss
'stylelint-config-recommended-scss',
'stylelint-config-recommended-vue/scss', 'stylelint-config-recommended-vue/scss',
'stylelint-config-html/vue', 'stylelint-config-html/vue',
'stylelint-config-recess-order', 'stylelint-config-recess-order',
@ -49,5 +50,7 @@ module.exports = {
'no-empty-source': null, 'no-empty-source': null,
'comment-no-empty': null, 'comment-no-empty': null,
'no-duplicate-selectors': null, 'no-duplicate-selectors': null,
'scss/comment-no-empty': null,
'selector-class-pattern': null,
}, },
} }

14
env/.env vendored
View File

@ -1,18 +1,12 @@
VITE_APP_TITLE = 'unibest' VITE_APP_TITLE = 'unibest'
VITE_APP_PORT = 9000 VITE_APP_PORT = 9000
# github actions 部署地址根路径,用在 manifest.config.ts 里面的 h5.router.base # h5部署网站的base配置到 manifest.config.ts 里的 h5.router.base
VITE_APP_PUBLIC_BASE=/ VITE_APP_PUBLIC_BASE=/
# TODO: 记得修改 VITE_UNI_APPID = 'H57F2ACE4'
VITE_UNI_APPID = 'H5871D791'
VITE_WX_APPID = 'wxa2abb91f64032a2b' VITE_WX_APPID = 'wxa2abb91f64032a2b'
# fallback lacaleen, zh-Hans, zh-Hant 等 # 非h5端只能使用完整的baseurl否则无法请求本地proxy只支持h5端
# 必须要在 lacale 文件夹中配置对应的 json 文件!!! # VITE_SERVER_BASEURL = '/api'
# 参考文档如下
# https://uniapp.dcloud.net.cn/tutorial/i18n.html
# https://uniapp.dcloud.net.cn/api/ui/locale.html#onlocalechange 打开页面后最下面的注意事项
VITE_FALLBACK_LOCALE = 'zh-Hans'
VITE_SERVER_BASEURL = 'https://ukw0y1.laf.run' VITE_SERVER_BASEURL = 'https://ukw0y1.laf.run'

View File

@ -2,5 +2,5 @@
NODE_ENV = 'development' NODE_ENV = 'development'
# 是否去除console 和 debugger # 是否去除console 和 debugger
VITE_DELETE_CONSOLE = false VITE_DELETE_CONSOLE = false
# 是否开启sourcemap
# VITE_SERVER_BASEURL = 'https://ukw0y1.laf.run' VITE_SHOW_SOURCEMAP = true

4
env/.env.production vendored
View File

@ -2,5 +2,5 @@
NODE_ENV = 'development' NODE_ENV = 'development'
# 是否去除console 和 debugger # 是否去除console 和 debugger
VITE_DELETE_CONSOLE = true VITE_DELETE_CONSOLE = true
# 是否开启sourcemap
# VITE_SERVER_BASEURL = 'https://xxx.com' VITE_SHOW_SOURCEMAP = false

View File

@ -1,7 +1,7 @@
{ {
"name": "unibest", "name": "unibest",
"type": "commonjs", "type": "commonjs",
"version": "1.5.0", "version": "2.0.0",
"description": "unibest - 最好的 uniapp 开发模板", "description": "unibest - 最好的 uniapp 开发模板",
"author": { "author": {
"name": "codercup", "name": "codercup",
@ -22,6 +22,7 @@
"pnpm": ">=7.30" "pnpm": ">=7.30"
}, },
"scripts": { "scripts": {
"upgrade": "npx @dcloudio/uvm@latest",
"dev:app": "uni -p app", "dev:app": "uni -p app",
"dev:app-android": "uni -p app-android", "dev:app-android": "uni -p app-android",
"dev:app-ios": "uni -p app-ios", "dev:app-ios": "uni -p app-ios",
@ -78,20 +79,20 @@
"bin-wrapper": "npm:bin-wrapper-china" "bin-wrapper": "npm:bin-wrapper-china"
}, },
"dependencies": { "dependencies": {
"@dcloudio/uni-app": "3.0.0-4000720240327002", "@dcloudio/uni-app": "3.0.0-4000820240401001",
"@dcloudio/uni-app-plus": "3.0.0-4000720240327002", "@dcloudio/uni-app-plus": "3.0.0-4000820240401001",
"@dcloudio/uni-components": "3.0.0-4000720240327002", "@dcloudio/uni-components": "3.0.0-4000820240401001",
"@dcloudio/uni-h5": "3.0.0-4000720240327002", "@dcloudio/uni-h5": "3.0.0-4000820240401001",
"@dcloudio/uni-mp-alipay": "3.0.0-4000720240327002", "@dcloudio/uni-mp-alipay": "3.0.0-4000820240401001",
"@dcloudio/uni-mp-baidu": "3.0.0-4000720240327002", "@dcloudio/uni-mp-baidu": "3.0.0-4000820240401001",
"@dcloudio/uni-mp-jd": "3.0.0-4000720240327002", "@dcloudio/uni-mp-jd": "3.0.0-4000820240401001",
"@dcloudio/uni-mp-kuaishou": "3.0.0-4000720240327002", "@dcloudio/uni-mp-kuaishou": "3.0.0-4000820240401001",
"@dcloudio/uni-mp-lark": "3.0.0-4000720240327002", "@dcloudio/uni-mp-lark": "3.0.0-4000820240401001",
"@dcloudio/uni-mp-qq": "3.0.0-4000720240327002", "@dcloudio/uni-mp-qq": "3.0.0-4000820240401001",
"@dcloudio/uni-mp-toutiao": "3.0.0-4000720240327002", "@dcloudio/uni-mp-toutiao": "3.0.0-4000820240401001",
"@dcloudio/uni-mp-weixin": "3.0.0-4000720240327002", "@dcloudio/uni-mp-weixin": "3.0.0-4000820240401001",
"@dcloudio/uni-mp-xhs": "3.0.0-4000720240327002", "@dcloudio/uni-mp-xhs": "3.0.0-4000820240401001",
"@dcloudio/uni-quickapp-webview": "3.0.0-4000720240327002", "@dcloudio/uni-quickapp-webview": "3.0.0-4000820240401001",
"dayjs": "1.11.10", "dayjs": "1.11.10",
"pinia": "2.0.36", "pinia": "2.0.36",
"pinia-plugin-persistedstate": "3.2.1", "pinia-plugin-persistedstate": "3.2.1",
@ -103,22 +104,21 @@
"@commitlint/cli": "^18.4.3", "@commitlint/cli": "^18.4.3",
"@commitlint/config-conventional": "^18.4.3", "@commitlint/config-conventional": "^18.4.3",
"@dcloudio/types": "^3.4.8", "@dcloudio/types": "^3.4.8",
"@dcloudio/uni-automator": "3.0.0-4000720240327002", "@dcloudio/uni-automator": "3.0.0-4000820240401001",
"@dcloudio/uni-cli-shared": "3.0.0-4000720240327002", "@dcloudio/uni-cli-shared": "3.0.0-4000820240401001",
"@dcloudio/uni-stacktracey": "3.0.0-4000720240327002", "@dcloudio/uni-stacktracey": "3.0.0-4000820240401001",
"@dcloudio/vite-plugin-uni": "3.0.0-4000720240327002", "@dcloudio/vite-plugin-uni": "3.0.0-4000820240401001",
"@iconify-json/carbon": "^1.1.27", "@iconify-json/carbon": "^1.1.27",
"@types/node": "^20.11.5", "@types/node": "^20.11.5",
"@types/wechat-miniprogram": "^3.4.7", "@types/wechat-miniprogram": "^3.4.7",
"@typescript-eslint/eslint-plugin": "^6.15.0", "@typescript-eslint/eslint-plugin": "^6.15.0",
"@typescript-eslint/parser": "^6.15.0", "@typescript-eslint/parser": "^6.15.0",
"@uni-helper/vite-plugin-uni-components": "^0.0.8",
"@uni-helper/vite-plugin-uni-layouts": "^0.1.7", "@uni-helper/vite-plugin-uni-layouts": "^0.1.7",
"@uni-helper/vite-plugin-uni-manifest": "^0.2.3", "@uni-helper/vite-plugin-uni-manifest": "^0.2.3",
"@uni-helper/vite-plugin-uni-pages": "^0.2.15", "@uni-helper/vite-plugin-uni-pages": "^0.2.15",
"@uni-helper/vite-plugin-uni-platform": "^0.0.4", "@uni-helper/vite-plugin-uni-platform": "^0.0.4",
"@unocss/preset-legacy-compat": "^0.59.1", "@unocss/preset-legacy-compat": "^0.59.1",
"@vue/runtime-core": "^3.3.13", "@vue/runtime-core": "^3.4.21",
"@vue/tsconfig": "^0.1.3", "@vue/tsconfig": "^0.1.3",
"autoprefixer": "^10.4.16", "autoprefixer": "^10.4.16",
"commitlint": "^18.4.3", "commitlint": "^18.4.3",
@ -139,9 +139,9 @@
"stylelint": "^16.0.2", "stylelint": "^16.0.2",
"stylelint-config-html": "^1.1.0", "stylelint-config-html": "^1.1.0",
"stylelint-config-recess-order": "^4.4.0", "stylelint-config-recess-order": "^4.4.0",
"stylelint-config-recommended-scss": "^14.0.0",
"stylelint-config-recommended-vue": "^1.5.0", "stylelint-config-recommended-vue": "^1.5.0",
"stylelint-config-standard": "^35.0.0", "stylelint-config-standard": "^35.0.0",
"stylelint-config-standard-scss": "^12.0.0",
"stylelint-prettier": "^5.0.0", "stylelint-prettier": "^5.0.0",
"terser": "^5.26.0", "terser": "^5.26.0",
"typescript": "^4.9.5", "typescript": "^4.9.5",

View File

@ -1,10 +0,0 @@
# 本文件会在依赖包安装时执行,用以生成 `src/manifest.json`
# 如果不存在 `src/manifest.json` 会运行报错,提示找不到 `src/manifest.json`
# 如果中途自己删除了 'src/manifest.json' 文件,记得手动执行本文件,可以右键 `Run Code` 快速执行
if test -f ./src/manifest.json; then
echo ./src/manifest.json 存在
else
touch ./src/manifest.json
echo "{}" >./src/manifest.json
fi

View File

@ -1,17 +0,0 @@
# pnpm build:app 之后会生成 unpackage/dist/build/app
# 我要把它改名为 unpackage/dist/build/unibest_app_build
# 只有存在新的 app 文件时,才执行这些操作!!否则会误删!!
if test -d ./dist/build/app; then
echo '存在新打包出来的app'
cd ./dist/build/
# 1、删除旧的 rename 后的文件夹
if test -d './unibest_app_build'; then
rm -rf ./unibest_app_build
fi
# 2、把 app 命名为 unibest_app_build
mv ./app ./unibest_app_build
fi

View File

@ -1,6 +0,0 @@
<!-- 本文件会自动导入 -->
<template>
<span>
<slot />
</span>
</template>

42
src/hooks/useRequest.ts Normal file
View File

@ -0,0 +1,42 @@
type IUseRequestOptions<T> = {
/** 是否立即执行如果是则在onLoad执行 */
immediate?: boolean
/** 初始化数据 */
initialData?: T
}
/**
* useRequest是一个定制化的请求钩子
* @param func Promise
* @param options {immediate, initialData}
* @param options.immediate true
* @param options.initialData undefined
* @returns {loading, error, data, run}
*/
export default function useRequest<T>(
func: () => Promise<IResData<T>>,
options: IUseRequestOptions<T> = { immediate: true },
) {
const loading = ref(false)
const error = ref(false)
const data = ref<T>()
const run = async () => {
loading.value = true
func()
.then((res) => {
data.value = res.data
error.value = false
})
.catch((err) => {
error.value = err
})
.finally(() => {
loading.value = false
})
}
onLoad(() => {
options.immediate && run()
})
return { loading, error, data, run }
}

9
src/i18n.d.ts vendored
View File

@ -1,9 +0,0 @@
/* eslint-disable no-unused-vars */
export {}
declare module 'vue' {
interface ComponentCustomProperties {
$t: (key: string, opt?: Record<string, any>) => string
$tm: (key: string, opt?: Record<string, any>) => [] | { [p: string]: any }
}
}

View File

@ -1,2 +1,3 @@
export { routeInterceptor } from './route' export { routeInterceptor } from './route'
export { requestInterceptor } from './request' export { requestInterceptor } from './request'
export { prototypeInterceptor } from './prototype'

View File

@ -0,0 +1,13 @@
export const prototypeInterceptor = {
install() {
// 解决低版本手机不识别 array.at() 导致运行报错的问题
if (typeof Array.prototype.at !== 'function') {
// eslint-disable-next-line no-extend-native
Array.prototype.at = function (index: number) {
if (index < 0) return this[this.length + index]
if (index >= this.length) return undefined
return this[index]
}
}
},
}

View File

@ -1,13 +1,16 @@
/* eslint-disable no-param-reassign */ /* eslint-disable no-param-reassign */
import qs from 'qs' import qs from 'qs'
import { useUserStore } from '@/store' import { useUserStore } from '@/store'
import { platform } from '@/utils/platform'
export type CustomRequestOptions = UniApp.RequestOptions & { export type CustomRequestOptions = UniApp.RequestOptions & {
query?: Record<string, any> query?: Record<string, any>
/** 出错时是否隐藏错误提示 */
hideErrorToast?: boolean
} & IUniUploadFileOptions // 添加uni.uploadFile参数类型 } & IUniUploadFileOptions // 添加uni.uploadFile参数类型
// 请求基地址 // 请求基地址
const baseURL = import.meta.env.VITE_SERVER_BASEURL const baseUrl = import.meta.env.VITE_SERVER_BASEURL
// 拦截器配置 // 拦截器配置
const httpInterceptor = { const httpInterceptor = {
@ -22,19 +25,19 @@ const httpInterceptor = {
options.url += `?${queryStr}` options.url += `?${queryStr}`
} }
} }
// 非 http 开头需拼接地址
// 1. 非 http 开头需拼接地址
if (!options.url.startsWith('http')) { if (!options.url.startsWith('http')) {
options.url = baseURL + options.url options.url = baseUrl + options.url
// TIPS: 如果需要对接多个后端服务,也可以在这里处理,拼接成所需要的地址
} }
// 2. 请求超时 // 1. 请求超时
options.timeout = 10000 // 10s options.timeout = 10000 // 10s
// 3. 添加小程序端请求头标识 // 2. (可选)添加小程序端请求头标识
options.header = { options.header = {
platform: 'mp-weixin', // 可选值与 uniapp 定义的平台一致,告诉后台来源 platform, // 可选,与 uniapp 定义的平台一致,告诉后台来源
...options.header, ...options.header,
} }
// 4. 添加 token 请求头标识 // 3. 添加 token 请求头标识
const userStore = useUserStore() const userStore = useUserStore()
const { token } = userStore.userInfo as unknown as IUserInfo const { token } = userStore.userInfo as unknown as IUserInfo
if (token) { if (token) {

View File

@ -21,7 +21,7 @@ const isDev = import.meta.env.DEV
const navigateToInterceptor = { const navigateToInterceptor = {
// 注意这里的url是 '/' 开头的,如 '/pages/index/index',跟 'pages.json' 里面的 path 不同 // 注意这里的url是 '/' 开头的,如 '/pages/index/index',跟 'pages.json' 里面的 path 不同
invoke({ url }: { url: string }) { invoke({ url }: { url: string }) {
console.log(url) // /pages/route-interceptor/index?name=feige&age=30 // console.log(url) // /pages/route-interceptor/index?name=feige&age=30
const path = url.split('?')[0] const path = url.split('?')[0]
let needLoginPages: string[] = [] let needLoginPages: string[] = []
// 为了防止开发时出现BUG这里每次都获取一下。生产环境可以移到函数外性能更好 // 为了防止开发时出现BUG这里每次都获取一下。生产环境可以移到函数外性能更好
@ -30,18 +30,17 @@ const navigateToInterceptor = {
} else { } else {
needLoginPages = _needLoginPages needLoginPages = _needLoginPages
} }
console.log(needLoginPages.includes(path)) const isNeedLogin = needLoginPages.includes(path)
if (!isNeedLogin) {
if (needLoginPages.includes(path)) { return true
const isLogin = isLogined()
if (isLogin) {
return true
}
const redirectRoute = `${loginRoute}?redirect=${encodeURIComponent(url)}`
uni.navigateTo({ url: redirectRoute })
return false
} }
return true const hasLogin = isLogined()
if (hasLogin) {
return true
}
const redirectRoute = `${loginRoute}?redirect=${encodeURIComponent(url)}`
uni.navigateTo({ url: redirectRoute })
return false
}, },
} }

View File

@ -3,10 +3,3 @@
<slot /> <slot />
</view> </view>
</template> </template>
<style lang="scss">
.default-layout {
height: 100vh;
overflow: auto;
}
</style>

View File

@ -1,5 +1,5 @@
<template> <template>
<view class="text-center p-4"> <view class="demo-layout">
<slot /> <slot />
</view> </view>
</template> </template>

View File

@ -1,8 +1,7 @@
import { createSSRApp } from 'vue' import { createSSRApp } from 'vue'
import App from './App.vue' import App from './App.vue'
import store from './store' import store from './store'
import { routeInterceptor, requestInterceptor } from './interceptors' import { routeInterceptor, requestInterceptor, prototypeInterceptor } from './interceptors'
import 'virtual:svg-icons-register'
import 'virtual:uno.css' import 'virtual:uno.css'
import '@/style/index.scss' import '@/style/index.scss'
@ -11,6 +10,7 @@ export function createApp() {
app.use(store) app.use(store)
app.use(routeInterceptor) app.use(routeInterceptor)
app.use(requestInterceptor) app.use(requestInterceptor)
app.use(prototypeInterceptor)
return { return {
app, app,
} }

View File

@ -1,6 +1,6 @@
{ {
"name": "unibest", "name": "unibest-base",
"appid": "H5871D791", "appid": "H57F2ACE4",
"description": "", "description": "",
"versionName": "1.0.0", "versionName": "1.0.0",
"versionCode": "100", "versionCode": "100",
@ -71,7 +71,6 @@
"enable": false "enable": false
}, },
"vueVersion": "3", "vueVersion": "3",
"locale": "zh-Hans",
"h5": { "h5": {
"router": { "router": {
"base": "/" "base": "/"

View File

@ -1,19 +0,0 @@
# 分包配置
`vite.config.ts` 中进行配置。
```ts
import { defineConfig } from 'vite'
import UniPages from '@uni-helper/vite-plugin-uni-pages'
export default defineConfig({
plugins: [
UniPages({
// ... 其他配置
subPackages: [
'src/pages-sub', // 是个数组,可以配置多个
],
}),
],
})
```

View File

@ -59,6 +59,14 @@
"style": { "style": {
"navigationBarTitleText": "请求" "navigationBarTitleText": "请求"
} }
},
{
"path": "pages/index/request2",
"type": "page",
"layout": "demo",
"style": {
"navigationBarTitleText": "请求"
}
} }
], ],
"subPackages": [] "subPackages": []

View File

@ -16,27 +16,19 @@
鸽友们好我是 鸽友们好我是
<text class="text-red-500">菲鸽</text> <text class="text-red-500">菲鸽</text>
</view> </view>
<view class="text-center mt-8"> <view class="text-center mt-8 text-#fff">
<wd-button type="primary" @click="gotoPage('request')">去请求页</wd-button> <wd-button type="primary" @click="gotoPage('request')">去请求页</wd-button>
<wd-button type="primary" @click="gotoPage('request2')" class="ml-2">
去请求页2 (请求状态一体化)
</wd-button>
</view> </view>
<view class="text-center py-4">
当前平台是
<text class="text-red-500">{{ PLATFORM.platform }}</text>
</view>
<view class="text-center desc mt-10">设计稿样式编写</view>
<view class="text-center desc">设计稿是750pxcss里面全部写rpx 即可</view>
</view> </view>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import PLATFORM from '@/utils/platform'
// //
const { safeAreaInsets } = uni.getSystemInfoSync() const { safeAreaInsets } = uni.getSystemInfoSync()
console.log(PLATFORM)
const gotoPage = (page: string) => { const gotoPage = (page: string) => {
uni.navigateTo({ uni.navigateTo({
url: `/pages/index/${page}`, url: `/pages/index/${page}`,

View File

@ -19,16 +19,21 @@
<view class="text-center text-2xl mt-2 mb-8">最好用的 uniapp 开发模板</view> <view class="text-center text-2xl mt-2 mb-8">最好用的 uniapp 开发模板</view>
<view class="text-justify max-w-100 m-auto text-4 indent mb-2">{{ description }}</view> <view class="text-justify max-w-100 m-auto text-4 indent mb-2">{{ description }}</view>
<view class="mt-8 text-center"> <view class="text-center mt-8">
<text class="text-green-400">当前模板分支base</text> 当前平台是
<text class="text-green-500">{{ PLATFORM.platform }}</text>
</view>
<view class="text-center mt-4">
模板分支是
<text class="text-green-500">base</text>
</view> </view>
</view> </view>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import PLATFORM from '@/utils/platform'
// //
const { safeAreaInsets } = uni.getSystemInfoSync() const { safeAreaInsets } = uni.getSystemInfoSync()
const author = ref('菲鸽') const author = ref('菲鸽')
const description = ref( const description = ref(
'unibest 是一个集成了多种工具和技术的 uniapp 开发模板,由 uniapp + Vue3 + Ts + Vite4 + UnoCss + UniUI + VSCode 构建,模板具有代码提示、自动格式化、统一配置、代码片段等功能,并内置了许多常用的基本组件和基本功能,让你编写 uniapp 拥有 best 体验。', 'unibest 是一个集成了多种工具和技术的 uniapp 开发模板,由 uniapp + Vue3 + Ts + Vite4 + UnoCss + UniUI + VSCode 构建,模板具有代码提示、自动格式化、统一配置、代码片段等功能,并内置了许多常用的基本组件和基本功能,让你编写 uniapp 拥有 best 体验。',

View File

@ -8,35 +8,35 @@
</route> </route>
<template> <template>
<view class="mt-6"> <view class="p-6 text-center">
<!-- http://localhost:9000/#/pages/index/request -->
<button @click="getFoo" class="my-4">测试 GET 请求</button>
<view class="text-xl">请求数据如下</view>
<view class="text-green h-10">{{ JSON.stringify(data) }}</view>
<view class="text-xl">完整数据</view>
<view class="text-green h-20">{{ JSON.stringify(originalData) }}</view>
<button @click="postFoo" class="my-4">测试 POST 请求</button>
<view class="text-xl">请求数据如下</view>
<view class="text-green h-10">{{ JSON.stringify(data2) }}</view>
<button class="my-8" type="warn" @click="reset">一键清空数据</button>
<view class="my-2">使用的是 laf 云后台</view> <view class="my-2">使用的是 laf 云后台</view>
<view class="text-green-400">我的推荐码可以获得佣金</view> <view class="text-green-400">我的推荐码可以获得佣金</view>
<!-- #ifdef H5 --> <!-- #ifdef H5 -->
<view class="my-2 text-center"> <view class="my-2">
<a class="my-2 text-center" :href="recommendUrl" target="_blank">{{ recommendUrl }}</a> <a class="my-2" :href="recommendUrl" target="_blank">{{ recommendUrl }}</a>
</view> </view>
<!-- #endif --> <!-- #endif -->
<!-- #ifndef H5 --> <!-- #ifndef H5 -->
<view class="my-2 text-left text-sm">{{ recommendUrl }}</view> <view class="my-2 text-left text-sm">{{ recommendUrl }}</view>
<!-- #endif --> <!-- #endif -->
<!-- http://localhost:9000/#/pages/index/request -->
<button @click="getFoo" class="my-6">1.测试 GET 请求</button>
<view class="text-xl">请求数据如下</view>
<view class="text-green h-10">{{ JSON.stringify(data) }}</view>
<view class="text-xl">完整数据</view>
<view class="text-green h-16">{{ JSON.stringify(originalData) }}</view>
<button @click="postFoo" class="my-6">2.测试 POST 请求</button>
<view class="text-xl">请求数据如下</view>
<view class="text-green h-10">{{ JSON.stringify(data2) }}</view>
<button class="my-6" type="warn" @click="reset">3.一键清空数据</button>
</view> </view>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { getFooAPI, postFooAPI, IFooItem } from '@/service/foo' import { getFooAPI, postFooAPI, IFooItem } from '@/service/index/foo'
const recommendUrl = ref('http://laf.run/signup?code=ohaOgIX') const recommendUrl = ref('http://laf.run/signup?code=ohaOgIX')
@ -44,6 +44,7 @@ onLoad(() => {
getFoo() getFoo()
postFoo() postFoo()
}) })
const originalData = ref<IResData<IFooItem>>() const originalData = ref<IResData<IFooItem>>()
const data = ref<IFooItem>() const data = ref<IFooItem>()
const getFoo = async () => { const getFoo = async () => {

View File

@ -0,0 +1,30 @@
<route lang="json5">
{
layout: 'demo',
style: {
navigationBarTitleText: '请求',
},
}
</route>
<template>
<view class="p-6 text-center">
<!-- http://localhost:9000/#/pages/index/request -->
<button @click="getFoo" class="my-6">测试 GET 请求</button>
<view class="text-xl">请求数据如下</view>
<view v-if="loading" class="text-blue h-10">加载中...</view>
<view v-else class="text-green h-10">{{ JSON.stringify(data) }}</view>
<button class="my-6" type="warn" @click="reset">一键清空数据</button>
</view>
</template>
<script lang="ts" setup>
import { getFooAPI, IFooItem } from '@/service/index/foo'
const { loading, data, run } = useRequest<IFooItem>(() => getFooAPI('菲鸽'), { immediate: true })
const getFoo = () => run()
const reset = () => {
data.value = undefined
}
</script>

14
src/shime-uni.d.ts vendored
View File

@ -1,14 +0,0 @@
export {}
declare module 'vue' {
type Hooks = App.AppInstance & Page.PageInstance
interface ComponentCustomOptions extends Hooks {
$uv?: any
}
}
declare global {
interface Uni {
$uv?: any
}
}

View File

@ -1,5 +1,3 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
/* eslint-disable no-unused-vars */
// 全局要用的类型放到这里 // 全局要用的类型放到这里
type IResData<T> = { type IResData<T> = {

View File

@ -22,10 +22,11 @@ export const http = <T>(options: CustomRequestOptions) => {
reject(res) reject(res)
} else { } else {
// 其他错误 -> 根据后端错误信息轻提示 // 其他错误 -> 根据后端错误信息轻提示
uni.showToast({ !options.hideErrorToast &&
icon: 'none', uni.showToast({
title: (res.data as IResData<T>).msg || '请求错误', icon: 'none',
}) title: (res.data as IResData<T>).msg || '请求错误',
})
reject(res) reject(res)
} }
}, },

View File

@ -8,7 +8,7 @@ export const getIsTabbar = () => {
return false return false
} }
const pages = getCurrentPages() const pages = getCurrentPages()
const lastPage = getArrElementByIdx(pages, -1) const lastPage = pages.at(-1)
const currPath = lastPage.route const currPath = lastPage.route
return !!pagesJson.tabBar.list.find((e) => e.pagePath === currPath) return !!pagesJson.tabBar.list.find((e) => e.pagePath === currPath)
} }
@ -22,7 +22,7 @@ export const currRoute = () => {
const pages = getCurrentPages() const pages = getCurrentPages()
console.log('pages:', pages) console.log('pages:', pages)
const lastPage = getArrElementByIdx(pages, -1) const lastPage = pages.at(-1)
const currRoute = (lastPage as any).$page const currRoute = (lastPage as any).$page
// console.log('lastPage.$page:', currRoute) // console.log('lastPage.$page:', currRoute)
// console.log('lastPage.$page.fullpath:', currRoute.fullPath) // console.log('lastPage.$page.fullpath:', currRoute.fullPath)
@ -105,9 +105,3 @@ export const getNeedLoginPages = (): string[] => getAllPages('needLogin').map((p
* path * path
*/ */
export const needLoginPages: string[] = getAllPages('needLogin').map((page) => page.path) export const needLoginPages: string[] = getAllPages('needLogin').map((page) => page.path)
export const getArrElementByIdx = (arr: any[], index: number) => {
if (index < 0) return arr[arr.length + index]
if (index >= arr.length) return undefined
return arr[index]
}

View File

@ -4,7 +4,10 @@
"skipLibCheck": true, "skipLibCheck": true,
"module": "ESNext", "module": "ESNext",
"moduleResolution": "Node", "moduleResolution": "Node",
"resolveJsonModule": true,
"noImplicitThis": true,
"allowSyntheticDefaultImports": true, "allowSyntheticDefaultImports": true,
"allowJs": true,
"sourceMap": true, "sourceMap": true,
"baseUrl": ".", "baseUrl": ".",
"paths": { "paths": {
@ -12,13 +15,7 @@
}, },
"outDir": "dist", "outDir": "dist",
"lib": ["esnext", "dom"], "lib": ["esnext", "dom"],
"types": [ "types": ["@dcloudio/types", "@types/wechat-miniprogram", "wot-design-uni/global.d.ts"]
"@dcloudio/types",
"@types/wechat-miniprogram",
"wot-design-uni/global.d.ts",
"./components.d.ts",
"./global.d.ts"
]
}, },
"vueCompilerOptions": { "vueCompilerOptions": {
"target": 3, "target": 3,

View File

@ -8,12 +8,7 @@ import {
transformerVariantGroup, transformerVariantGroup,
} from 'unocss' } from 'unocss'
import { import { presetApplet, presetRemRpx, transformerAttributify } from 'unocss-applet'
presetApplet,
presetRemRpx,
transformerApplet,
transformerAttributify,
} from 'unocss-applet'
// @see https://unocss.dev/presets/legacy-compat // @see https://unocss.dev/presets/legacy-compat
import presetLegacyCompat from '@unocss/preset-legacy-compat' import presetLegacyCompat from '@unocss/preset-legacy-compat'
@ -36,8 +31,8 @@ if (!isH5) {
} }
export default defineConfig({ export default defineConfig({
presets: [ presets: [
presetApplet({ enable: !isH5 }),
...presets, ...presets,
presetApplet(),
// 支持图标需要搭配图标库eg: @iconify-json/carbon, 使用 `<button class="i-carbon-sun dark:i-carbon-moon" />` // 支持图标需要搭配图标库eg: @iconify-json/carbon, 使用 `<button class="i-carbon-sun dark:i-carbon-moon" />`
presetIcons({ presetIcons({
scale: 1.2, scale: 1.2,
@ -71,7 +66,6 @@ export default defineConfig({
prefixedOnly: true, prefixedOnly: true,
prefix: 'fg', prefix: 'fg',
}), }),
transformerApplet(),
], ],
rules: [ rules: [
[ [

View File

@ -1,43 +0,0 @@
// TIPS: 很多用户无法安装这个插件所以先注释掉了如果您可以安装成功那就可以放开这个注释以及下面的viteImagemin配置
// 注意小程序有主包2M的限制所以一般图片会放到图片服务器不放本地那就不需要这个插件
// 如果是开发h5或者app的可以自行安装
import viteImagemin from 'vite-plugin-imagemin'
export default (enabled: boolean) => {
if (!enabled) {
return undefined
}
return viteImagemin({
gifsicle: {
// gif图片压缩
optimizationLevel: 3, // 选择1到3之间的优化级别
interlaced: false, // 隔行扫描gif进行渐进式渲染
// colors: 2 // 将每个输出GIF中不同颜色的数量减少到num或更少。数字必须介于2和256之间。
},
optipng: {
// png
optimizationLevel: 7, // 选择0到7之间的优化级别
},
mozjpeg: {
// jpeg
quality: 20, // 压缩质量范围从0(最差)到100(最佳)。
},
pngquant: {
// png
quality: [0.8, 0.9], // Min和max是介于0(最差)到1(最佳)之间的数字类似于JPEG。达到或超过最高质量所需的最少量的颜色。如果转换导致质量低于最低质量图像将不会被保存。
speed: 4, // 压缩速度1(强力)到11(最快)
},
svgo: {
// svg压缩
plugins: [
{
name: 'removeViewBox',
},
{
name: 'removeEmptyAttrs',
active: false,
},
],
},
})
}

View File

@ -11,24 +11,14 @@ import UniLayouts from '@uni-helper/vite-plugin-uni-layouts'
import UniPlatform from '@uni-helper/vite-plugin-uni-platform' import UniPlatform from '@uni-helper/vite-plugin-uni-platform'
// @see https://github.com/uni-helper/vite-plugin-uni-manifest // @see https://github.com/uni-helper/vite-plugin-uni-manifest
import UniManifest from '@uni-helper/vite-plugin-uni-manifest' import UniManifest from '@uni-helper/vite-plugin-uni-manifest'
// @see https://github.com/uni-helper/vite-plugin-uni-components
import Components from '@uni-helper/vite-plugin-uni-components'
// @see https://unocss.dev/ // @see https://unocss.dev/
import UnoCSS from 'unocss/vite' import UnoCSS from 'unocss/vite'
// import autoprefixer from 'autoprefixer'
// @see https://github.com/jpkleemans/vite-svg-loader // @see https://github.com/jpkleemans/vite-svg-loader
import svgLoader from 'vite-svg-loader' import svgLoader from 'vite-svg-loader'
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
// @see https://github.com/vbenjs/vite-plugin-vue-setup-extend
import vueSetupExtend from 'vite-plugin-vue-setup-extend'
// @see https://github.com/vbenjs/vite-plugin-svg-icons
import AutoImport from 'unplugin-auto-import/vite' import AutoImport from 'unplugin-auto-import/vite'
// import viteCompression from 'vite-plugin-compression' import vueSetupExtend from 'vite-plugin-vue-setup-extend'
import ViteRestart from 'vite-plugin-restart'
import { visualizer } from 'rollup-plugin-visualizer' import { visualizer } from 'rollup-plugin-visualizer'
// import imagemin from './vite-plugins/imagemin' import ViteRestart from 'vite-plugin-restart'
console.log('process.platform -> ', process.platform)
// https://vitejs.dev/config/ // https://vitejs.dev/config/
export default ({ command, mode }) => { export default ({ command, mode }) => {
@ -40,13 +30,16 @@ export default ({ command, mode }) => {
// pnpm build:h5 时得到 => build production // pnpm build:h5 时得到 => build production
// pnpm dev:mp-weixin 时得到 => build development (注意区别command为build) // pnpm dev:mp-weixin 时得到 => build development (注意区别command为build)
// pnpm build:mp-weixin 时得到 => build production // pnpm build:mp-weixin 时得到 => build production
// pnpm dev:app 时得到 => build development (注意区别command为build)
// pnpm build:app 时得到 => build production
// dev 和 build 命令可以分别使用 .env.development 和 .env.production 的环境变量
const { UNI_PLATFORM } = process.env
console.log('UNI_PLATFORM -> ', UNI_PLATFORM) // 得到 mp-weixin, h5, app 等
// process.cwd(): 获取当前文件的目录跟地址
// loadEnv(): 返回当前环境env文件中额外定义的变量
const env = loadEnv(mode, path.resolve(process.cwd(), 'env')) const env = loadEnv(mode, path.resolve(process.cwd(), 'env'))
console.log('env -> ', env) const { VITE_APP_PORT, VITE_SERVER_BASEURL, VITE_DELETE_CONSOLE, VITE_SHOW_SOURCEMAP } = env
console.log('process.env.UNI_PLATFORM: ', process.env.UNI_PLATFORM) // 得到 mp-weixin, h5, app 等 console.log('环境变量 env -> ', env)
console.log('isH5: ', process.env.UNI_PLATFORM === 'h5') // 得到 mp-weixin, h5, app 等
return defineConfig({ return defineConfig({
envDir: './env', // 自定义env目录 envDir: './env', // 自定义env目录
@ -58,12 +51,11 @@ export default ({ command, mode }) => {
// homePage 通过 vue 文件的 route-block 的type="home"来设定 // homePage 通过 vue 文件的 route-block 的type="home"来设定
// pages 目录为 src/pages分包目录不能配置在pages目录下 // pages 目录为 src/pages分包目录不能配置在pages目录下
// subPackages: ['src/pages-sub'], // 是个数组可以配置多个但是不能为pages里面的目录 // subPackages: ['src/pages-sub'], // 是个数组可以配置多个但是不能为pages里面的目录
dts: 'src/types/uni-pages.d.ts',
}), }),
UniLayouts(), UniLayouts(),
UniPlatform(), UniPlatform(),
UniManifest(), UniManifest(),
// 自动安装 src/components 里面的组件为全局组件,非全局组件不要放到 src/components
Components(),
// UniXXX 需要在 Uni 之前引入 // UniXXX 需要在 Uni 之前引入
Uni(), Uni(),
UnoCSS(), UnoCSS(),
@ -71,47 +63,38 @@ export default ({ command, mode }) => {
svgLoader({ svgLoader({
defaultImport: 'url', // or 'raw' defaultImport: 'url', // or 'raw'
}), }),
createSvgIconsPlugin({
// 指定要缓存的文件夹
iconDirs: [path.resolve(process.cwd(), 'src/assets/svg')],
// 指定symbolId格式
symbolId: 'icon-[dir]-[name]',
}),
vueSetupExtend(),
AutoImport({ AutoImport({
imports: ['vue', 'uni-app'], imports: ['vue', 'uni-app'],
dts: 'src/auto-import.d.ts', dts: 'src/types/auto-import.d.ts',
// dirs: ['src/hooks'], // 自动导入 hooks dirs: ['src/hooks'], // 自动导入 hooks
eslintrc: { enabled: false }, eslintrc: { enabled: true },
vueTemplate: true, // default false vueTemplate: true, // default false
}), }),
// viteCompression(), vueSetupExtend(),
ViteRestart({ ViteRestart({
// 通过这个插件在修改vite.config.js文件则不需要重新运行也生效配置 // 通过这个插件在修改vite.config.js文件则不需要重新运行也生效配置
restart: ['vite.config.js'], restart: ['vite.config.js'],
}), }),
// h5环境增加编译时间 // h5环境增加编译时间
process.env.UNI_PLATFORM === 'h5' && { UNI_PLATFORM === 'h5' && {
name: 'html-transform', name: 'html-transform',
transformIndexHtml(html) { transformIndexHtml(html) {
return html.replace('%BUILD_DATE%', dayjs().format('YYYY-MM-DD HH:mm:ss')) return html.replace('%BUILD_DATE%', dayjs().format('YYYY-MM-DD HH:mm:ss'))
}, },
}, },
// 打包分析插件 // 打包分析插件h5 + 生产环境才弹出
mode === 'production' && UNI_PLATFORM === 'h5' &&
mode === 'production' &&
visualizer({ visualizer({
filename: './node_modules/.cache/visualizer/stats.html', filename: './node_modules/.cache/visualizer/stats.html',
open: true, open: true,
gzipSize: true, gzipSize: true,
brotliSize: true, brotliSize: true,
}), }),
// 这个图片压缩插件比较耗时,希望仅在生产环境使用
// TODO: 缓存每次压缩过的图片,已经压缩过的不再压缩
// imagemin(mode === 'production'),
], ],
define: { define: {
__UNI_PLATFORM__: JSON.stringify(process.env.UNI_PLATFORM), __UNI_PLATFORM__: JSON.stringify(UNI_PLATFORM),
}, },
css: { css: {
postcss: { postcss: {
@ -133,23 +116,26 @@ export default ({ command, mode }) => {
server: { server: {
host: '0.0.0.0', host: '0.0.0.0',
hmr: true, hmr: true,
port: Number.parseInt(env.VITE_APP_PORT, 10), port: Number.parseInt(VITE_APP_PORT, 10),
proxy: {
'/api': {
target: VITE_SERVER_BASEURL,
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ''),
},
},
}, },
build: { build: {
// 方便非h5端调试
sourcemap: VITE_SHOW_SOURCEMAP === 'true', // 默认是false
target: 'es6',
minify: 'terser', minify: 'terser',
terserOptions: { terserOptions: {
compress: { compress: {
drop_console: env.VITE_DELETE_CONSOLE === 'true', drop_console: VITE_DELETE_CONSOLE === 'true',
drop_debugger: env.VITE_DELETE_CONSOLE === 'true', drop_debugger: true,
}, },
}, },
// 解决windows系统对微信小程序自动关闭服务的问题
watch:
process.platform === 'win32' // 检测是否为 windows 系统
? {
exclude: ['node_modules/**', '/__uno.css'],
}
: null,
}, },
}) })
} }