feat(建页方案): 建页方案初始化文件调整
This commit is contained in:
parent
df36baf61d
commit
6b775b986c
@ -143,13 +143,14 @@ page.config.js 是 md 的结构化落地结果,不能脱离 md 自行新增业
|
||||
如果发现 page.config.js 或 index.vue 与 md 不一致,优先询问或按 md 同步,而不是反向猜测 md。
|
||||
生成 vue 页面时必须渐进式生成:先生成可预览底座,再按用户后续指令逐个补模块和接口。
|
||||
可预览底座只包含预加载、组件引用、图片工具、背景、基础顶部、标签容器和空内容占位,方便用户实时预览页面效果。
|
||||
新建页面只要生成 `index.vue`,必须补充统一加载动画:模板首层使用 `v-if="isLoading"` 展示居中的 `LoadingContent`,主页面内容使用 `v-else`,避免加载阶段提前挂载背景图和业务节点。`isLoading` 默认为 `true`,进入页面时至少执行一次 `completePreloading()`;即使 blocking 预加载列表为空,也要通过 `finally` 关闭 loading,防止页面卡死。
|
||||
新建页面只要生成 `index.vue`,必须补充统一加载动画:模板首层使用 `v-if="isLoading"` 展示居中的 `LoadingContent`,主页面内容使用 `v-else`,避免加载阶段提前挂载背景图和业务节点。`isLoading` 默认为 `true`,进入页面时至少执行一次 `completePreloading()`;`completePreloading()` 只负责阻塞图片预加载,不等待业务接口;即使 blocking 预加载列表为空,也要通过 `finally` 关闭 loading,防止页面卡死。
|
||||
页面只要使用接口,就必须从 `@/utils/appConnector.js` 引入 `connectToApp`,并在 `onMounted` 中先调用 `connectToAppHandler()`;所有初始化业务接口和需要请求头的接口必须放在 `connectToApp(() => { loadInitialPageData() })` 成功回调之后执行,确保 App 请求头已写入。图片预加载和接口初始化要拆成独立方法,允许并行启动,但 loading 动画只由图片预加载控制。
|
||||
业务模块不得一次性全部生成;抽奖、任务、排行榜、奖励、弹窗、接口对接都要等用户明确说生成哪一块再做。
|
||||
页面中的规则、奖励、历史、结果等弹窗模块必须统一使用公共组件 `src/components/MaskLayer.vue` 作为遮罩层和背景滚动锁定容器;弹窗内容放入默认插槽,需要点击遮罩空白关闭时,在插槽内再包一层全屏内容容器并使用 `@click.self` 关闭。
|
||||
开发预览阶段,样式优先靠近结构:能直接用内联样式表达的固定不变、一次性布局尺寸、间距、定位,直接写在模板内联样式里,方便实时调整并减少不必要的 class 拆分;可复用样式、状态样式、伪类/媒体查询/RTL 规则、复杂模块样式仍使用 class。
|
||||
动态样式不要优先使用 `:style="{ ... }"` 对象写法;涉及状态切换、选中态、方向、显隐、尺寸变化等动态效果时优先切换 class。只有必须绑定运行时数值且不适合枚举成 class 时,才使用动态 style。
|
||||
内联样式和 class 在普通静态场景下性能差异通常很小;需要避免的是大量节点重复生成动态 style 对象、频繁变更大段内联样式。开发结束或模块稳定后,再按复用性和可维护性统一抽成 class。
|
||||
使用 `itemCenter` 承载图片背景时,必须给组件写入按图片比例计算出的 `min-height`,避免图片未加载时内部信息挤在一起。计算方式:先确认组件在页面中的展示宽度(单位 vw),再读取图片实际宽高,`min-height = Math.ceil(展示宽度vw * 图片高度 / 图片宽度) + 'vw'`。如果组件放在网格或固定宽度容器里,展示宽度按该容器实际占用的 vw 计算;如果同一背景有多语言图片,取对应语言图片中最高的计算结果。
|
||||
普通业务模块一般不要提前设置 `min-height` 和 `line-height`;`min-height` 只在基础页面容器(如 `.full-page` / `.fullPage`)中按需使用。`itemCenter` 的 `min-height` 不在页面初建阶段预设,只在页面开发完成后确实需要稳定图片容器高度时再按图片比例补充;补充时先确认组件展示宽度(单位 vw),再读取图片实际宽高,`min-height = Math.ceil(展示宽度vw * 图片高度 / 图片宽度) + 'vw'`。为避免图片加载出来之前 `itemCenter` 容器高度异常撑高,补充 `min-height` 时同步补一个接近的 `max-height`,默认可按 `max-height = min-height + 1vw` 处理,例如 `min-height: 21vw; max-height: 22vw`。
|
||||
生成的 Vue 文件统一使用 `<style lang="scss" scoped>`;页面基础样式固定放在 style 块顶部,包括 `* { color: #fff; }`、`.fullPage {}`、响应式基础字号 media query。阿语等 RTL 规则也集中写在 style 块中,使用 `[dir='rtl'] xxx`,不要散在模板内联样式里。
|
||||
除基础 media query 中设置响应式字号外,页面内其它展示字号统一使用 `font-size: 1em`,不要再写 `vw`、`px` 或 `clamp()` 字号,方便所有文本跟随统一基准字号变化。
|
||||
模块配置中如果出现 `images.container` 或 `containerImages` 这类整块大背景图,生成 Vue 时统一使用 `itemCenter` 承载;容器宽度先写 `100vw`,父级用 flex 从上往下排列,`gap`、`padding`、`margin` 初始先写 `0`,不额外加边框虚线,后续由用户按预览继续调整。
|
||||
@ -167,6 +168,7 @@ page.config.js 是 md 的结构化落地结果,不能脱离 md 自行新增业
|
||||
新增 js/vue 文件尽量加中文注释。
|
||||
页面后续更新模块、接口或公共方法时,必须给新增/调整的方法和关键模块逻辑添加简短中文注释,说明用途、接口来源、字段映射或展示规则;模板里的主要 `div`、`section`、`itemCenter` 等结构模块也要补中文注释,说明当前块负责的视觉区域或业务含义;不要只堆代码,方便后续继续按模块迭代。
|
||||
页面任何模块都不要出现可见滚动条。新建或更新页面时,推荐页面根容器固定 `height: 100vh`、`overflow: hidden`,由内部主内容容器负责 `overflow-y: auto` 垂直滚动,并隐藏滚动条;需要滚动时允许内容滚动,但必须通过 `scrollbar-width: none`、`-ms-overflow-style: none` 和 `::-webkit-scrollbar { display: none; }` 隐藏可见滚动条。
|
||||
多 tab 或多分类列表如果内部包含大量固定图片、`itemCenter` 背景图、本地 OSS 图标,切换 tab 时优先使用 `v-show` 保留 tab 内容容器 DOM,避免 `v-if` 销毁重建导致固定图片反复加载;数据层仍按 tab 独立数组和独立 request token 处理,切换时可以继续重新请求接口刷新最新数据。
|
||||
docs 下文件和文件夹使用中文命名。
|
||||
页面底座以能运行、可预览、结构清楚、方便继续逐步补模块为目标。
|
||||
```
|
||||
@ -339,7 +341,7 @@ src/config/imageCacheVersion.js
|
||||
4. 两个列表都要走同一套 imageUrl/getImgName 规则,保证本地 OSS、线上 OSS、图片缓存和多语言后缀一致。
|
||||
5. 后台预加载在 blocking 完成、页面可见后执行,优先使用 requestIdleCallback,兼容时用 setTimeout。
|
||||
6. 后台预加载失败只记录日志,不影响页面展示和交互。
|
||||
7. 所有新建页面必须有统一加载动画:`isLoading=true`、`completePreloading()`、`try/catch/finally`、`<LoadingContent>{{ $t('loading') }}...</LoadingContent>`。加载态期间只渲染 loading 容器,不渲染正式页面背景、装饰图或业务模块。
|
||||
7. 所有新建页面必须有统一加载动画:`isLoading=true`、`completePreloading()`、`try/catch/finally`、`<LoadingContent>{{ $t('loading') }}...</LoadingContent>`。加载态期间只渲染 loading 容器,不渲染正式页面背景、装饰图或业务模块;`completePreloading()` 只处理图片预加载,业务接口统一提取到 `loadInitialPageData()` 等独立方法中。
|
||||
```
|
||||
|
||||
## 7. 完成后写回专属 md
|
||||
|
||||
@ -36,14 +36,15 @@ src/views/Activities/WorldCup/页面创建信息.md
|
||||
- 没填的字段,初版页面先不猜。
|
||||
- `页面创建信息.md` 是 `page.config.js` 和 `index.vue` 的生成来源;后续补需求先改 md,再同步代码。
|
||||
- 每轮可以指定同步方向:`md -> vue` 或 `vue -> md`;方向不明确且两边冲突时,先确认再改。
|
||||
- 新建页面只要生成 `index.vue`,都必须带统一加载动画:先展示 `LoadingContent`,关键图片和初始化完成后再展示正式页面。
|
||||
- 新建页面只要生成 `index.vue`,都必须带统一加载动画:先展示 `LoadingContent`,关键图片预加载完成后再展示正式页面;loading 只针对图片,不等待业务接口。
|
||||
- 页面只要使用接口,就必须引入 `connectToApp` 并先完成 App 连接;初始化接口统一放在 `connectToApp(() => { loadInitialPageData() })` 成功回调后执行,确保请求头已设置。图片预加载方法和接口初始化方法必须分离。
|
||||
- 页面根容器推荐固定 `height: 100vh`、`overflow: hidden`,内部主内容容器负责 `overflow-y: auto` 垂直滚动并隐藏滚动条。
|
||||
- 页面任何模块都不要出现可见滚动条。
|
||||
- 页面模块布局可以使用 flex column,模块间距按需求设置,常见活动页默认可用 `gap: 2vw`。
|
||||
- 能用内联样式直接表达的固定布局、尺寸、间距、定位,优先使用内联样式,方便实时调位置。
|
||||
- 可复用样式、伪类、媒体查询、RTL 规则和复杂状态样式可以写 class。
|
||||
- 动态选中态、显隐和尺寸变化可以使用方法返回内联 style 字符串;如果复用明显,再抽 class。
|
||||
- 使用 `itemCenter` 承载图片背景时,要按图片比例补 `min-height`,避免图片未加载时内部内容挤在一起。
|
||||
- 普通业务模块一般不要提前设置 `min-height` 和 `line-height`;`min-height` 只在基础页面容器(如 `.full-page` / `.fullPage`)中按需使用,`itemCenter` 的 `min-height` 只在页面开发完成后确实需要稳定图片容器高度时再补;补充时同步设置接近的 `max-height`,默认可按 `max-height = min-height + 1vw`,例如 `min-height: 21vw; max-height: 22vw`。
|
||||
- `itemCenter` 承载大背景图时,宽度优先写 `100vw`,父级从上往下 flex 排列。
|
||||
- `v-smart-img` 只用于项目自身静态图片,例如通过 `src/config/imagePaths.js` 中 `getPngUrl`、`getWebpUrl` 等方法,或活动页 `imageUrl`、`webpUrl` 等封装得到的图片地址。
|
||||
- 接口返回的远程图片链接不要使用 `v-smart-img`,直接用原生 `<img :src="接口字段">` 展示,不走本地图片缓存或智能图片指令。
|
||||
@ -53,6 +54,7 @@ src/views/Activities/WorldCup/页面创建信息.md
|
||||
- 对接 POST 接口时,如果接口没有业务参数,也必须传空对象 `{}`,不要省略 body。
|
||||
- 多 tab 或多分类列表不要共用同一个承载数组;每个 tab 使用独立数据源,避免接口慢返回或快速切换时数据混用。
|
||||
- 多 tab 列表请求建议使用每个 tab 独立的请求序号或 token,只忽略同 tab 内更旧的响应,不影响其他 tab 的缓存。
|
||||
- 多 tab 列表如果内部有大量固定图片、`itemCenter` 背景图或本地 OSS 图标,tab 内容容器优先使用 `v-show` 保留 DOM,避免每次切换时因 `v-if` 销毁重建导致固定图片反复加载;接口仍可在切换时重新请求最新数据。
|
||||
- 弹窗统一使用公共组件 `src/components/MaskLayer.vue`。规则、奖励、历史、结果等弹窗内容放在 `MaskLayer` 默认插槽内;需要点击空白关闭时,在插槽内包一层全屏容器并使用 `@click.self` 关闭。
|
||||
|
||||
## 3. 页面信息 md 模板
|
||||
|
||||
@ -17,11 +17,17 @@
|
||||
用途:背景图 + 内部绝对定位内容,是活动页最常用的图片容器。
|
||||
|
||||
```vue
|
||||
<itemCenter :imgUrl="imageUrl('rewardBg')" contentStyle="padding: 10vw 6vw;">
|
||||
<itemCenter
|
||||
:imgUrl="imageUrl('rewardBg')"
|
||||
style="width: 100vw; min-height: 21vw; max-height: 22vw"
|
||||
contentStyle="padding: 10vw 6vw;"
|
||||
>
|
||||
<!-- 内容 -->
|
||||
</itemCenter>
|
||||
```
|
||||
|
||||
开发完成后需要稳定图片容器高度时,按图片比例补 `min-height`,并同步补接近的 `max-height`,一般可用 `max-height = min-height + 1vw`,避免图片加载出来之前容器异常撑高。
|
||||
|
||||
### 1.3 topUser / TopUser
|
||||
|
||||
用途:前三名用户展示。不同页面可能有自己的 `components/topUser.vue`,新页面可先从参考页面复制一份再微调。
|
||||
@ -253,7 +259,7 @@ imageUrl('taskTypeGift') // 礼物任务类型图标
|
||||
```vue
|
||||
<MaskLayer :maskLayerShow="showPopup">
|
||||
<div
|
||||
style="width: 100vw; min-height: 100vh; display: flex; align-items: flex-start; justify-content: center; padding: 6vh 0 10vh; box-sizing: border-box;"
|
||||
style="width: 100vw; height: 100vh; display: flex; align-items: flex-start; justify-content: center; padding: 6vh 0 10vh; box-sizing: border-box;"
|
||||
@click.self="showPopup = false"
|
||||
>
|
||||
<!-- 弹窗内容模块:使用 itemCenter 或普通 div 承载弹窗背景和内容 -->
|
||||
@ -555,6 +561,8 @@ const { activeIndex, isRolling, startLottery } = useLotteryDraw({
|
||||
用途:把首屏关键图片和后续图片拆开。首屏关键图片参与进入页面加载动画;弹窗、非默认标签页、下方长背景等图片在页面进入后后台继续预加载。
|
||||
|
||||
```js
|
||||
import { connectToApp } from '@/utils/appConnector.js'
|
||||
|
||||
// 进入页面前必须完成的图片,加载完成后再结束 loading 动画。
|
||||
const blockingPreloadImageNames = pageConfig.preload?.blocking || []
|
||||
|
||||
@ -594,9 +602,30 @@ const preloadBackgroundImages = () => {
|
||||
setTimeout(run, 0)
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
await preloadBlockingImages()
|
||||
isLoading.value = false
|
||||
preloadBackgroundImages()
|
||||
// 首屏预加载:只处理阻塞图片,不等待业务接口。
|
||||
const completePreloading = async () => {
|
||||
try {
|
||||
await preloadBlockingImages()
|
||||
} finally {
|
||||
isLoading.value = false
|
||||
preloadBackgroundImages()
|
||||
}
|
||||
}
|
||||
|
||||
// 页面初始化接口:连接 App 并写入请求头后,再单独拉取业务数据。
|
||||
const loadInitialPageData = async () => {
|
||||
// await getPageData()
|
||||
}
|
||||
|
||||
// 连接 App:使用接口的页面必须在 connectToApp 成功回调后再发起业务接口请求。
|
||||
const connectToAppHandler = async () => {
|
||||
await connectToApp(() => {
|
||||
loadInitialPageData()
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
completePreloading()
|
||||
connectToAppHandler()
|
||||
})
|
||||
```
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user