This commit is contained in:
houjunxiang
2025-10-09 18:19:55 +08:00
parent f2ffc65094
commit 386f1e7466
1553 changed files with 284685 additions and 32820 deletions

43
nx/hooks/useGridCol.js Normal file
View File

@@ -0,0 +1,43 @@
import { ref, onMounted, onUnmounted } from 'vue'
import { debounce } from 'lodash' // 或手动实现防抖
/**
* 动态计算网格列数的 Hook
* @param {number[]} breakpoints - 断点数组,如 [400, 600] 表示 400px 和 600px 两个断点
* @param {number[]} cols - 对应断点的列数,如 [2, 3, 4] 表示:
* - 屏幕宽度 < 400px: 2 列
* - 400px ≤ 宽度 < 600px: 3 列
* - 宽度 ≥ 600px: 4 列
* @returns {Object} { gridCol } - 返回响应式的列数引用
*/
export function useGridCol(breakpoints = [400, 600], cols = [2, 3, 4]) {
const gridCol = ref(cols[cols.length - 1]) // 默认取最大值(大屏列数)
const calculateGridCol = () => {
const { windowWidth } = uni.getSystemInfoSync()
let selectedCol = cols[cols.length - 1] // 默认值
// 遍历断点,找到匹配的列数
for (let i = 0; i < breakpoints.length; i++) {
if (windowWidth < breakpoints[i]) {
selectedCol = cols[i]
break
}
}
gridCol.value = selectedCol
}
onMounted(() => {
calculateGridCol() // 初始化计算
uni.onWindowResize(calculateGridCol) // 监听窗口变化
})
onUnmounted(() => {
// 清理监听(部分平台可能需要手动实现)
if (typeof uni.offWindowResize === 'function') {
uni.offWindowResize(calculateGridCol)
}
})
return { gridCol }
}

View File

@@ -0,0 +1,88 @@
import { ref, reactive, onMounted, watch, unref } from 'vue'
import { onReachBottom } from '@dcloudio/uni-app'
export function useListData({ searchParams, api, needInitListData = false, processData }) {
// 定义响应式数据
const initListData = ref(needInitListData)
const loadingData = ref(true)
const pageParams = reactive({
pageNo: 1,
pageSize: 10,
order: 'desc',
column: 'createTime'
})
const total = ref(0)
const loadStatus = ref('loadmore')
const listData = ref([])
// 模拟获取数据的方法
const getListData = async () => {
const params = {
...unref(searchParams),
...pageParams
}
let { records, total: pageTotal } = await api(params)
total.value = pageTotal
if (processData) {
records = processData(records)
}
return records
}
// 页面底部触底加载更多
const scrollToLower = async () => {
if (listData.value.length >= total.value) {
loadStatus.value = 'nomore'
return
} else {
loadStatus.value = 'loading'
}
pageParams.pageNo++
await loadMore()
}
// 加载更多数据
const loadMore = async () => {
const newData = await getListData()
listData.value = [...listData.value, ...newData]
if (listData.value.length >= total.value) loadStatus.value = 'nomore'
}
// 初始化数据
const getInitData = async () => {
loadStatus.value = 'loadmore'
pageParams.pageNo = 1
total.value = 0
listData.value = []
loadingData.value = true
let data = await getListData().finally(() => {
loadingData.value = false
})
listData.value = data
if (listData.value.length >= total.value) loadStatus.value = 'nomore'
}
// 组件挂载时执行初始化
onMounted(() => {
if (initListData.value) {
getInitData()
}
})
onReachBottom(() => {
scrollToLower()
})
// 监听滚动到底部事件
// 注意:在实际应用中,你需要根据你的框架或库来监听滚动到底部的事件
return {
initListData,
loadingData,
pageParams,
total,
loadStatus,
listData,
loadMore,
scrollToLower,
getInitData
}
}

View File

@@ -0,0 +1,46 @@
// useScreenOrientation.ts
import { onUnmounted } from 'vue'
//orientation:'portrait' | 'landscape'
export function useScreenOrientation() {
// 锁定屏幕方向
const lockOrientation = orientation => {
try {
if (typeof plus !== 'undefined' && plus.screen) {
const currentOrientation = plus.screen.orientation
if (currentOrientation !== orientation) {
plus.screen.lockOrientation(orientation)
return true
}
}
} catch (e) {
console.warn('锁定方向失败:', e)
return false
}
return false
}
// 解锁屏幕方向
const unlockOrientation = () => {
try {
if (typeof plus !== 'undefined' && plus.screen) {
plus.screen.unlockOrientation()
return true
}
} catch (e) {
console.warn('解锁方向失败:', e)
return false
}
return false
}
// 自动在组件卸载时解锁
onUnmounted(() => {
unlockOrientation()
})
return {
lockOrientation,
unlockOrientation
}
}