Appearance
详情页加载逻辑
说明: 以新闻、商品详情页为例。
版本说明
时间 | 修改人 | 备注 |
---|---|---|
2025-04-23 | YG | 初始化文档 |
一、页面加载流程
- 在
onLoad
中,打开loading动画,调用nxhSDKLib.$init()
包裹页面逻辑 - 获取主题色配置
store.dispatch("getAppConfig", query)
- 获取详情页模版配置
nxhSDK.getData("cms_page_info", { template_type: 3 })
- 根据页面参数获取文章或商品ID,获取详情数据
nxhSDK.getData("cms_article_detail", { id: '' })
- 关闭loading动画
二、页面交互规范
- 详情页需要支持分享功能,自定义分享调用
onShareAppMessage
和onShareTimeline
方法 - 详情内容可滚动,需要用
<scroll-view scroll-y>
标签包裹内容 - 默认进入,要先展示loading动画,接口调用结束后,有数据则展示数据内容,无数据时,使用
<n-empty-data />
组件占位。 - 接口请求成功或失败后,都要关闭 loading 动画
- 新闻详情页根据类型展示:
- 文章类型:用富文本
<rich-text-render />
展示 - 图集类型:顶部展示图片轮播图,下方展示文字内容
- 视频类型:顶部展示视频,下方展示文字内容
- 下载类型:上方展示文字内容,下方展示下载列表
- 文章类型:用富文本
- 商品详情页轮播图可点击放大,购买等操作按钮固定在屏幕下方。
三、代码实现与解析
1. 打开loading动画,调用 nxhSDKLib.$init()
包裹页面逻辑
vue
<script setup>
onLoad((query) => {
uni.showLoading({
title: '加载中...',
mask: true
})
nxhSDKLib.$init(() => {
// 写你的页面接口调用
})
})
</script>
2. 获取主题色配置 store.dispatch("getAppConfig", query)
调用了该代码后,会自动获取主题色,并存储在 store 中,方便其他页面调用。
vue
<script setup>
const styleJson = computed(() => store.state?.appConfig?.style)
onLoad((query) => {
nxhSDKLib.$init(() => {
store.dispatch("getAppConfig", query)
})
})
</script>
3. 获取页面模版配置 nxhSDK.getData("cms_page_info", { template_type: 2 })
- 调用SDK接口获取页面配置信息
- 解析返回的配置数据,更新列表配置和列表类型
vue
<script setup>
const getPageInfo = () => {
nxhSDK.getData("cms_page_info", { template_type: 3 }).then((res) => {
const { page_config } = res?.result?.info
if (page_config) {
pageConfig.value = JSON.parse(page_config || '{}')
}
})
}
</script>
4. 获取id,调用详情接口 nxhSDK.getData("cms_article_detail", { id: query.did })
vue
<script setup>
const fetchNewsDetail = async (did) => {
try {
const data = await nxhSDK.getData("cms_article_detail", {id: did, show_template: 1, show_content: 1, show_attr: 1})
const {
id, title, title_sub, updated_at, tag_name, content, attach, attach_ext, real_template_type
} = data.result
newsDetailBlock.id = id;
newsDetailBlock.title = title;
if (tag_name) {
newsDetailBlock.tags = tag_name.replace(/,/g, ',').split(',').filter(tag => tag.trim() !== '');
} else {
newsDetailBlock.tags = [];
}
newsDetailBlock.date = updated_at;
newsDetailBlock.content = decodeURIComponent(content);
newsDetailBlock.attach = JSON.parse(attach || '[]');
newsDetailBlock.attach_ext = JSON.parse(attach_ext || '[]').map((i) => ({ ...i, type: 'link'}));
newsDetailBlock.real_template_type = real_template_type;
console.warn('fetchNewsDetail1', data, newsDetailBlock);
} catch (error) {
console.error('Error fetching news detail:', error);
}
};
</script>
5. 关闭loading动画
vue
<script setup>
onLoad((query) => {
nxhSDKLib.$init(() => {
// 详情接口请求后
uni.hideLoading();
loading.value = false;
})
})
</script>
四、完整代码示例
vue
<template>
<news-detail :block="newsDetailBlock" :pageConfig="pageConfig"></news-detail>
</template>
<script setup>
import { onMounted, reactive, ref, shallowRef } from 'vue';
import {nxhSDK} from "@/nxhsdk.module.min";
import NewsDetail from '../components/NewsDetail.vue';
import { onLoad, onShareAppMessage } from '@dcloudio/uni-app';
const store = nxhSDK.useSDKStore();
const loading = ref(true);
const currentPageComponent = shallowRef(NewsDetail);
const pageConfig = ref({
titleConfig: {
paddingVertical: '8',
paddingHorizontal: '0',
fontSize: '16',
fontWeight: 'bolder',
color: '#2A3547',
textAlign: 'left',
backgroundColor: '#fff',
},
// 标签配置
tagConfig: {
tagPaddingVertical: '2',
tagPaddingHorizontal: '8',
tagBorderRadius: '4',
fontSize: '12',
fontWeight: 'normal',
color: '#2A3547',
tagBgColor: '#f4f4f4',
},
// 日期配置
dateConfig: {
color: '#2A3547',
fontSize: '12',
},
// 分隔线配置
dividerConfig: {
type: 'line',
height: '30',
borderColor: '#EBEDF0',
borderStyle: 'solid',
borderMargin: '0',
}
})
const newsDetailBlock = reactive({
id: '',
title: '',
tags: [],
date: '',
content: '',
attach: [], // 附件-文件
attach_ext: [], // 附件-外链
real_template_type: '', // 文章类型
});
const getPageInfo = () => {
nxhSDK.getData("cms_page_info", { template_type: 3 }).then((res) => {
console.log('getPageInfo', res)
const { page_config } = res?.result?.info
if (page_config) {
pageConfig.value = JSON.parse(page_config || '{}')
}
})
}
const fetchNewsDetail = async (did) => {
try {
const data = await nxhSDK.getData("cms_article_detail", {id: did, show_template: 1, show_content: 1, show_attr: 1})
const {
id, title, title_sub, updated_at, tag_name, content, attach, attach_ext, real_template_type
} = data.result
newsDetailBlock.id = id;
newsDetailBlock.title = title;
if (tag_name) {
newsDetailBlock.tags = tag_name.replace(/,/g, ',').split(',').filter(tag => tag.trim() !== '');
} else {
newsDetailBlock.tags = [];
}
newsDetailBlock.date = updated_at;
newsDetailBlock.content = decodeURIComponent(content);
newsDetailBlock.attach = JSON.parse(attach || '[]');
newsDetailBlock.attach_ext = JSON.parse(attach_ext || '[]').map((i) => ({ ...i, type: 'link'}));
newsDetailBlock.real_template_type = real_template_type;
console.warn('fetchNewsDetail1', data, newsDetailBlock);
} catch (error) {
console.error('Error fetching news detail:', error);
}
};
onShareAppMessage(() => {
return {
title: `${newsDetailBlock.title}`,
path: `/news/detail/index?did=${newsDetailBlock.id}&appid=${store.state.app_id}`
}
})
onLoad(async (query) => {
uni.showLoading({
title: '加载中',
});
const id = query.did;
getPageInfo()
await fetchNewsDetail(id);
uni.hideLoading();
loading.value = false;
});
</script>
<style scoped>
</style>