upload project source code
This commit is contained in:
254
前端源码/uni-app/utils/uni-compat.ts
Normal file
254
前端源码/uni-app/utils/uni-compat.ts
Normal file
@@ -0,0 +1,254 @@
|
||||
/**
|
||||
* uni-app API 兼容层 - 用于 H5 环境
|
||||
* 提供最小的 API 实现,保持代码不变
|
||||
*/
|
||||
|
||||
// Toast 提示
|
||||
export function showToast(options: { title: string; icon?: string; duration?: number }) {
|
||||
const toast = document.createElement('div')
|
||||
toast.className = 'uni-toast'
|
||||
toast.textContent = options.title
|
||||
toast.style.cssText = `
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
background: rgba(0, 0, 0, 0.7);
|
||||
color: white;
|
||||
padding: 12px 24px;
|
||||
border-radius: 8px;
|
||||
font-size: 14px;
|
||||
z-index: 10000;
|
||||
max-width: 80%;
|
||||
text-align: center;
|
||||
`
|
||||
document.body.appendChild(toast)
|
||||
|
||||
setTimeout(() => {
|
||||
document.body.removeChild(toast)
|
||||
}, options.duration || 2000)
|
||||
}
|
||||
|
||||
// Loading 提示
|
||||
let loadingElement: HTMLElement | null = null
|
||||
|
||||
export function showLoading(options: { title?: string; mask?: boolean }) {
|
||||
hideLoading()
|
||||
|
||||
loadingElement = document.createElement('div')
|
||||
loadingElement.className = 'uni-loading'
|
||||
loadingElement.innerHTML = `
|
||||
<div style="
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: ${options.mask ? 'rgba(0, 0, 0, 0.3)' : 'transparent'};
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 10000;
|
||||
">
|
||||
<div style="
|
||||
background: rgba(0, 0, 0, 0.7);
|
||||
color: white;
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
text-align: center;
|
||||
">
|
||||
<div style="
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
border: 3px solid rgba(255, 255, 255, 0.3);
|
||||
border-top-color: white;
|
||||
border-radius: 50%;
|
||||
animation: spin 1s linear infinite;
|
||||
margin: 0 auto 10px;
|
||||
"></div>
|
||||
<div>${options.title || '加载中...'}</div>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
|
||||
// 添加旋转动画
|
||||
if (!document.getElementById('uni-loading-style')) {
|
||||
const style = document.createElement('style')
|
||||
style.id = 'uni-loading-style'
|
||||
style.textContent = `
|
||||
@keyframes spin {
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
`
|
||||
document.head.appendChild(style)
|
||||
}
|
||||
|
||||
document.body.appendChild(loadingElement)
|
||||
}
|
||||
|
||||
export function hideLoading() {
|
||||
if (loadingElement) {
|
||||
document.body.removeChild(loadingElement)
|
||||
loadingElement = null
|
||||
}
|
||||
}
|
||||
|
||||
// 本地存储
|
||||
export function setStorageSync(key: string, data: any) {
|
||||
try {
|
||||
localStorage.setItem(key, JSON.stringify(data))
|
||||
} catch (e) {
|
||||
console.error('setStorageSync error:', e)
|
||||
}
|
||||
}
|
||||
|
||||
export function getStorageSync(key: string) {
|
||||
try {
|
||||
const data = localStorage.getItem(key)
|
||||
return data ? JSON.parse(data) : null
|
||||
} catch (e) {
|
||||
console.error('getStorageSync error:', e)
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
export function removeStorageSync(key: string) {
|
||||
try {
|
||||
localStorage.removeItem(key)
|
||||
} catch (e) {
|
||||
console.error('removeStorageSync error:', e)
|
||||
}
|
||||
}
|
||||
|
||||
// 导航
|
||||
export function navigateTo(options: { url: string }) {
|
||||
const path = options.url.split('?')[0]
|
||||
const query = options.url.split('?')[1]
|
||||
const params = new URLSearchParams(query)
|
||||
|
||||
if (window.vueRouter) {
|
||||
window.vueRouter.push({
|
||||
path,
|
||||
query: Object.fromEntries(params)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export function redirectTo(options: { url: string }) {
|
||||
const path = options.url.split('?')[0]
|
||||
const query = options.url.split('?')[1]
|
||||
const params = new URLSearchParams(query)
|
||||
|
||||
if (window.vueRouter) {
|
||||
window.vueRouter.replace({
|
||||
path,
|
||||
query: Object.fromEntries(params)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export function navigateBack(options?: { delta?: number }) {
|
||||
if (window.vueRouter) {
|
||||
window.vueRouter.go(-(options?.delta || 1))
|
||||
}
|
||||
}
|
||||
|
||||
export function switchTab(options: { url: string }) {
|
||||
navigateTo(options)
|
||||
}
|
||||
|
||||
// 系统信息
|
||||
export function getSystemInfoSync() {
|
||||
return {
|
||||
statusBarHeight: 0,
|
||||
windowWidth: window.innerWidth,
|
||||
windowHeight: window.innerHeight,
|
||||
platform: 'h5'
|
||||
}
|
||||
}
|
||||
|
||||
// 请求
|
||||
export function request(options: any) {
|
||||
return fetch(options.url, {
|
||||
method: options.method || 'GET',
|
||||
headers: options.header || {},
|
||||
body: options.data ? JSON.stringify(options.data) : undefined
|
||||
})
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
options.success?.({ data })
|
||||
return { data }
|
||||
})
|
||||
.catch(err => {
|
||||
options.fail?.(err)
|
||||
throw err
|
||||
})
|
||||
}
|
||||
|
||||
// 上传文件
|
||||
export function uploadFile(options: any) {
|
||||
const formData = new FormData()
|
||||
formData.append(options.name, options.filePath)
|
||||
|
||||
if (options.formData) {
|
||||
Object.keys(options.formData).forEach(key => {
|
||||
formData.append(key, options.formData[key])
|
||||
})
|
||||
}
|
||||
|
||||
return fetch(options.url, {
|
||||
method: 'POST',
|
||||
headers: options.header || {},
|
||||
body: formData
|
||||
})
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
options.success?.({ data })
|
||||
return { data }
|
||||
})
|
||||
.catch(err => {
|
||||
options.fail?.(err)
|
||||
throw err
|
||||
})
|
||||
}
|
||||
|
||||
// 选择图片
|
||||
export function chooseImage(options: any) {
|
||||
const input = document.createElement('input')
|
||||
input.type = 'file'
|
||||
input.accept = 'image/*'
|
||||
input.multiple = options.count > 1
|
||||
|
||||
input.onchange = (e: any) => {
|
||||
const files = Array.from(e.target.files || [])
|
||||
const tempFilePaths = files.map((file: any) => URL.createObjectURL(file))
|
||||
options.success?.({ tempFilePaths, tempFiles: files })
|
||||
}
|
||||
|
||||
input.click()
|
||||
}
|
||||
|
||||
// 全局 uni 对象
|
||||
export const uni = {
|
||||
showToast,
|
||||
showLoading,
|
||||
hideLoading,
|
||||
setStorageSync,
|
||||
getStorageSync,
|
||||
removeStorageSync,
|
||||
navigateTo,
|
||||
redirectTo,
|
||||
navigateBack,
|
||||
switchTab,
|
||||
getSystemInfoSync,
|
||||
request,
|
||||
uploadFile,
|
||||
chooseImage
|
||||
}
|
||||
|
||||
// 挂载到全局
|
||||
if (typeof window !== 'undefined') {
|
||||
(window as any).uni = uni
|
||||
}
|
||||
|
||||
export default uni
|
||||
Reference in New Issue
Block a user