添加配置项,首页

This commit is contained in:
cbb
2025-12-23 17:41:05 +08:00
parent d4d5cdb335
commit 0cf5bb9dad
12 changed files with 317 additions and 22 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
unpackage

37
App.vue
View File

@@ -1,15 +1,32 @@
<script>
export default {
onLaunch: function() {
console.log('App Launch')
},
onShow: function() {
console.log('App Show')
},
onHide: function() {
console.log('App Hide')
<script setup>
import { onLaunch, onShow, onHide } from '@dcloudio/uni-app'
import { useTokenStore } from '@/stores/token'
import { reLaunch } from '@/utils/router'
/** 静默登录逻辑 */
const silentLogin = async () => {
const tokenStore = useTokenStore()
if (tokenStore.token && !tokenStore.isTokenExpired()) {
console.log('去验证token')
return
}
// 没有token去登录页
reLaunch('/pages/login/login?id=1')
}
onLaunch(() => {
console.log('App Launch111')
silentLogin()
})
onShow(() => {
console.log('App Show222')
})
onHide(() => {
console.log('App Hide333')
})
</script>
<style>

3
constants/storageKeys.js Normal file
View File

@@ -0,0 +1,3 @@
export const STORAGE_KEYS = {
TOKEN: 'token',
};

View File

@@ -1,5 +1,6 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<script>
@@ -13,8 +14,10 @@
<!--preload-links-->
<!--app-context-->
</head>
<body>
<div id="app"><!--app-html--></div>
<script type="module" src="/main.js"></script>
</body>
</html>

13
main.js
View File

@@ -6,17 +6,20 @@ import './uni.promisify.adaptor'
Vue.config.productionTip = false
App.mpType = 'app'
const app = new Vue({
...App
...App
})
app.$mount()
// #endif
// #ifdef VUE3
import { createSSRApp } from 'vue'
import * as Pinia from 'pinia'
export function createApp() {
const app = createSSRApp(App)
return {
app
}
const app = createSSRApp(App)
app.use(Pinia.createPinia())
return {
app,
Pinia, // 此处必须将 Pinia 返回
}
}
// #endif

View File

@@ -3,7 +3,13 @@
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "uni-app"
"navigationBarTitleText": "首页"
}
},
{
"path": "pages/login/login",
"style": {
"navigationStyle": "custom"
}
}
],

View File

@@ -8,8 +8,7 @@
</template>
<script setup>
import { ref } from 'vue'
import { onReady } from '@dcloudio/uni-app'
import { onMounted, ref } from 'vue'
const cb = v => {
console.log(v)
}
@@ -27,10 +26,8 @@
// }
// }
const title = ref('你好')
onReady(() => {
console.log('启动了!!')
})
const title = ref('你112好')
</script>
<style>

15
pages/login/login.vue Normal file
View File

@@ -0,0 +1,15 @@
<template>
<view>{{ name }}</view>
</template>
<script setup>
import { ref } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
const name = ref('登1录')
onLoad(e => {
console.log('接收==', e.id)
})
</script>
<style></style>

42
stores/token.js Normal file
View File

@@ -0,0 +1,42 @@
import { defineStore } from 'pinia';
import { ref } from 'vue';
import { STORAGE_KEYS } from '@/constants/storageKeys';
import { getToken, removeToken } from '@/utils/storage';
/** 登录状态 */
export const useTokenStore = defineStore(STORAGE_KEYS.TOKEN, () => {
// 从本地存储获取token
const token = ref(getToken() || null);
const isLogin = ref(!!token.value);
/** 设置token并保存到本地 */
const setToken = (newToken) => {
token.value = newToken;
isLogin.value = true;
setToken(newToken);
};
/** 清除token */
const clearToken = () => {
token.value = null;
isLogin.value = false;
removeToken()
};
/** 检查token是否有效可扩展过期时间判断 */
const checkToken = () => {
// 简单判断token存在且不为空
return !!token.value;
};
/** 验证token是否过期实际项目中可添加过期时间判断 */
const isTokenExpired = () => {
// 示例如果token中包含过期时间这里可以判断
// 例如const expireTime = parseInt(token.value.split('.')[1]);
// return Date.now() > expireTime * 1000;
return false; // 默认不过期
};
return { token, isLogin, setToken, clearToken, checkToken, isTokenExpired };
})

126
utils/request.js Normal file
View File

@@ -0,0 +1,126 @@
import { getToken, removeToken } from './storage';
const BASE_URL = 'xxxxx'
/**
* 网络请求封装
* @param {Object} options 请求参数
* @returns {Promise}
*/
const request = (options) => {
// 默认配置
const defaultOptions = {
url: '',
method: 'GET',
data: {},
header: {
'Content-Type': 'application/json' // 默认请求内容类型
}
}
// 合并配置
const config = { ...defaultOptions, ...options }
// 请求拦截添加token等通用header
if (getToken()) {
config.header['Authorization'] = 'Bearer ' + getToken()
}
// 显示加载状态(可选)
if (options.loading !== false) {
uni.showLoading({
title: '加载中...',
mask: true
})
}
return new Promise((resolve, reject) => {
uni.request({
url: BASE_URL + config.url,
method: config.method,
data: config.data,
timeout: 10000, // 请求超时时间
header: config.header,
success: (response) => {
// 响应拦截:根据状态码处理
if (response.statusCode === 200) {
// 这里可以根据后端数据格式调整
// 例如if (response.data.code === 0) {...}
resolve(response.data)
} else {
// 状态码错误处理
handleError(response.statusCode, response.data)
reject(response)
}
},
fail: (error) => {
// 网络错误处理
uni.showToast({
title: '网络异常,请检查网络连接',
icon: 'none',
duration: 2000
})
reject(error)
},
complete: () => {
// 隐藏加载状态
if (options.loading !== false) {
uni.hideLoading()
}
}
})
})
}
/**
* 错误处理函数
* @param {Number} statusCode HTTP状态码
* @param {Object} data 响应数据
*/
const handleError = (statusCode, data) => {
switch (statusCode) {
case 401:
uni.showModal({
title: '提示',
content: '登录已过期,请重新登录',
showCancel: false,
success: () => {
// 清除本地存储的token并跳转到登录页
removeToken()
uni.navigateTo({
url: '/pages/login/index'
})
}
})
break
case 403:
uni.showToast({
title: '没有权限访问',
icon: 'none',
duration: 2000
})
break
case 404:
uni.showToast({
title: '请求资源不存在',
icon: 'none',
duration: 2000
})
break
case 500:
uni.showToast({
title: '服务器内部错误',
icon: 'none',
duration: 2000
})
break
default:
uni.showToast({
title: data.message || '请求失败,请重试',
icon: 'none',
duration: 2000
})
}
}
export default request

66
utils/router.js Normal file
View File

@@ -0,0 +1,66 @@
// 统一页面跳转工具函数
/**
* 辅助函数:拼接 URL 参数
* @param {string} url - 页面路径,如 '/pages/home/home'
* @param {object} params - 参数对象,如 { id: 123, name: 'test' }
* @returns {string} 拼接后的完整 url
*/
const appendParams = (url, params) => {
if (!params || Object.keys(params).length === 0) {
return url
}
const query = Object.entries(params).map(([key, value]) => {
// 处理复杂类型(如对象、数组)需序列化
if (typeof value === 'object') {
value = encodeURIComponent(JSON.stringify(value))
} else {
value = encodeURIComponent(String(value))
}
return `${key}=${value}`
}).join('&')
return url.includes('?') ? `${url}&${query}` : `${url}?${query}`
}
/**
* 普通跳转(保留返回)
*/
export const navigateTo = (url, params = {}) => {
const finalUrl = appendParams(url, params)
return uni.navigateTo({ url: finalUrl })
}
/**
* 关闭当前页,跳转到应用内某个页面(不可返回)
*/
export const redirectTo = (url, params = {}) => {
const finalUrl = appendParams(url, params)
return uni.redirectTo({ url: finalUrl })
}
/**
* 关闭所有页面,打开到应用内某个页面
*/
export const reLaunch = (url, params = {}) => {
const finalUrl = appendParams(url, params)
return uni.reLaunch({ url: finalUrl })
}
/**
* 返回上一页(可指定 delta
*/
export const navigateBack = (delta = 1) => {
return uni.navigateBack({ delta })
}
/**
* 跳转到 tabBar 页面(只能用 switchTab
*/
export const switchTab = (url, params = {}) => {
if (Object.keys(params).length > 0) {
console.warn('switchTab 不支持携带参数,请使用全局状态或 storage 传递')
}
return uni.switchTab({ url })
}

16
utils/storage.js Normal file
View File

@@ -0,0 +1,16 @@
import { STORAGE_KEYS } from '@/constants/storageKeys'
/** 保存 token */
export const setToken = (v) => {
return uni.setStorageSync(STORAGE_KEYS.TOKEN, v)
}
/** 获取 token */
export const getToken = () => {
return uni.getStorageSync(STORAGE_KEYS.TOKEN) || ''
}
/** 清楚 token */
export const removeToken = () => {
return uni.removeStorageSync(STORAGE_KEYS.TOKEN)
}