hookehuyr

feat(分页): 为每页添加独立的导航配置支持

重构分页逻辑,将导航配置从全局改为每页独立
新增 page_nav_props_by_index 存储每页导航属性
添加 normalizePaginatorProps 方法规范化分页符属性
......@@ -15,6 +15,8 @@ export function usePagination(formDataRef, options = {}) {
const enable_pagination = ref(false)
// 当前页索引
const current_page_index = ref(0)
// 每一页的导航配置(由相邻的 paginator 控件决定)
const page_nav_props_by_index = ref([])
// 过滤后的分页:剔除被隐藏(disabled)的字段,但保留空页占位,确保分页总数与 paginator 一致
const filtered_pages = computed(() => {
......@@ -43,30 +45,62 @@ export function usePagination(formDataRef, options = {}) {
})
/**
* 规范化分页符属性为导航配置
* @param {Object} props 分页符的 component_props
* @returns {{prev_text: string, next_text: string, prev_disabled: boolean}} 导航配置
*/
const normalizePaginatorProps = (props = {}) => {
// 中文文案默认值
const nav = { prev_text: '上一页', next_text: '下一页', prev_disabled: false }
if (props.back_title) nav.prev_text = props.back_title
if (props.next_title) nav.next_text = props.next_title
// 是否允许返回:true 允许,false 不允许
if (typeof props.is_back === 'boolean') nav.prev_disabled = !props.is_back
return nav
}
/**
* 构建分页分组
* @description 优先按 paginator 分组;若仅一组则按固定大小分片
* @description 优先按 paginator 分组;并为每一页记录其对应的导航文案与返回策略
*/
const buildPages = () => {
const result = []
const pages = []
const navs = []
let cur = []
// 当前页导航配置,默认值;当遇到 paginator 时更新为“下一页”的导航
let current_nav = normalizePaginatorProps()
// 连续的 paginator 需要忽略,避免出现空分页
let last_was_paginator = false
formDataRef.value.forEach(item => {
const tag = item.component_props?.tag
// 分隔符 paginator 作为分页分组边界
// 分隔符 paginator 作为分页分组边界,同时决定后续一页的导航配置
if (tag === 'paginator') {
// 若前一个也是 paginator,则忽略本次(不产生空页)
// 连续分页符:忽略后者,保留先前设置,避免空页与属性覆盖
if (last_was_paginator) return
if (cur.length) result.push(cur)
cur = []
// 如果当前已有内容,先把“这一页”收束,并使用当前导航配置
if (cur.length) {
pages.push(cur)
navs.push(current_nav)
cur = []
}
// 更新“下一页”的导航配置为本分页符设置
current_nav = normalizePaginatorProps(item.component_props)
last_was_paginator = true
return
}
// 普通字段加入当前页
cur.push(item.key)
last_was_paginator = false
})
if (cur.length) result.push(cur)
if (result.length <= 1) {
// 收尾:最后一页
if (cur.length) {
pages.push(cur)
navs.push(current_nav)
}
// 若未显式分页,仅按固定大小分片,并为每一页设置默认导航
if (pages.length <= 1) {
const size = 8
const keys = formDataRef.value.filter(i => i.component_props?.tag !== 'paginator').map(i => i.key)
const chunked = []
......@@ -74,8 +108,10 @@ export function usePagination(formDataRef, options = {}) {
chunked.push(keys.slice(i, i + size))
}
pages_raw.value = chunked.length ? chunked : [keys]
page_nav_props_by_index.value = (chunked.length ? chunked : [keys]).map(() => normalizePaginatorProps())
} else {
pages_raw.value = result
pages_raw.value = pages
page_nav_props_by_index.value = navs
}
}
......@@ -94,26 +130,12 @@ export function usePagination(formDataRef, options = {}) {
/**
* 分页导航配置
* @description 仅从 tag 为 paginator 的字段中读取导航文案与可返回状态
* @description 根据当前页索引读取对应的分页符导航文案与返回控制
* @returns {{prev_text: string, next_text: string, prev_disabled: boolean}}
*/
const page_nav = computed(() => {
// 默认文案与状态
let prev_text = '上一页'
let next_text = '下一页'
let prev_disabled = false
// 仅查找 tag=paginator 的字段并提取其 component_props
const paginator_item = formDataRef.value.find(i => i?.component_props?.tag === 'paginator')
if (paginator_item && paginator_item.component_props) {
const props = paginator_item.component_props
if (props.back_title) prev_text = props.back_title
if (props.next_title) next_text = props.next_title
// is_back 表示是否允许返回
if (typeof props.is_back === 'boolean') prev_disabled = !props.is_back
}
return { prev_text, next_text, prev_disabled }
const def = normalizePaginatorProps()
return page_nav_props_by_index.value[current_page_index.value] || def
})
/**
......