本文档基于实际项目经验,提供 QuickBox 框架的最佳实践和使用建议。
import QuickBox from 'quickbox';
// 检查是否已添加到桌面
const isInstalled = await QuickBox.ShortcutUtils.checkInstalled();
if (!isInstalled) {
// 引导用户添加桌面
}
// 获取加桌方式
const method = QuickBox.ShortcutUtils.getInstallMethod();
if (method === 'install') {
// 华为/OPPO:使用 API 方式
await QuickBox.ShortcutUtils.install({
success: () => {
console.log('添加成功');
},
fail: (err) => {
console.log('添加失败', err);
}
});
} else {
// 其他厂商:使用组件方式
// 在模板中使用 <shortcut-button> 组件
}华为/OPPO(使用 API):
// script
async onAddDesktop() {
const method = QuickBox.ShortcutUtils.getInstallMethod();
if (method === 'install') {
try {
await QuickBox.ShortcutUtils.install({
success: () => {
prompt.showToast({ message: '添加成功' });
},
fail: (err) => {
prompt.showToast({ message: '添加失败,请重试' });
}
});
} catch (error) {
console.error('添加桌面失败', error);
}
}
}其他厂商(使用组件):
<!-- template -->
<shortcut-button
value="添加至桌面"
add-type="8"
onclick="onAddDesktop"
></shortcut-button>在章节阅读页等关键页面,可以拦截返回操作,引导用户添加桌面:
onBackPress() {
const isInstalled = await QuickBox.ShortcutUtils.checkInstalled();
if (!isInstalled) {
// 显示加桌引导弹窗
this.showAddDesktopDialog = true;
return true; // 阻止返回
}
return false; // 允许返回
}import QuickBox from 'quickbox';
// 方式1:单独获取各厂商配置
const huaweiConfig = await QuickBox.ConfigManager.getHuaweiConfig(
'https://api.example.com/app/config/getHuaweiConfig'
);
await QuickBox.huaweiPay({
applicationID: huaweiConfig.applicationID,
publicKey: huaweiConfig.publicKey,
productId: 'product_123',
amount: 1000,
orderInfo: 'ORDER_123'
});
// 方式2:自动根据当前厂商获取配置
const config = await QuickBox.ConfigManager.getConfigByVendor({
huawei: 'https://api.example.com/app/config/getHuaweiConfig',
xiaomi: 'https://api.example.com/app/config/getXiaomiConfig',
oppo: 'https://api.example.com/app/config/getOppoConfig',
vivo: 'https://api.example.com/app/config/getVivoConfig'
});建议在应用启动时获取并缓存配置:
// app.ux
let paymentConfigs = {};
async onCreate() {
// 预加载支付配置
try {
const vendor = QuickBox.getVendorInfo().vendor;
if (vendor === 'huawei' || vendor === 'honor') {
paymentConfigs.huawei = await QuickBox.ConfigManager.getHuaweiConfig(
'https://api.example.com/app/config/getHuaweiConfig'
);
}
// ... 其他厂商
} catch (error) {
console.error('加载支付配置失败', error);
}
}import QuickBox from 'quickbox';
// 配置统一参数(会自动添加到所有请求)
QuickBox.Request.configure({
baseURL: 'https://api.example.com',
baseParams: {
max_app_id: 'YOUR_APP_ID',
max_version: '1.0.0',
max_package: 'com.example.app',
max_brand: QuickBox.getVendorInfo().vendor,
max_platform: 1,
max_os: 1
},
timeout: 20000,
headers: {
'Content-Type': 'application/json'
}
});// 添加Token到请求头
QuickBox.Request.addRequestInterceptor((options) => {
const token = getToken(); // 从存储中获取token
return {
...options,
header: {
...options.header,
Authorization: token
}
};
});// 统一处理响应数据
QuickBox.Request.addResponseInterceptor((response) => {
// 假设后端返回格式为 { code: 0, data: {...}, msg: 'success' }
if (response.code === 0) {
return response.data;
} else {
throw new Error(response.msg || '请求失败');
}
});QuickBox.Request.configure({
onUnauthorized: async () => {
// 清除token
await QuickBox.removeStorage('token');
// 跳转到登录页
QuickBox.navigateTo({ uri: '/pages/login' });
}
});try {
const data = await QuickBox.Request.get('/api/users');
} catch (error) {
// 错误已经被拦截器处理,这里可以做额外处理
console.error('请求失败', error);
}小米需要使用 <ad-clickable-area> 包裹点击区域:
<!-- template -->
<ad
id="ad"
adid="{{nativeAdData.adId}}"
type="native"
class="ad"
onadclick="onAdClick"
onadclose="onAdClose"
>
<ad-clickable-area if="{{isMi}}" style="width: 100%;height: 100%">
<div class="adbtn" onclick="onAdClick">
<text>查看详情</text>
</div>
</ad-clickable-area>
</ad>// script
import QuickBox from 'quickbox';
async initNativeAd() {
const isMi = QuickBox.isXiaomi();
// 创建原生广告
const nativeAd = QuickBox.createNativeAd({
adUnitId: 'YOUR_AD_UNIT_ID',
adCount: 1 // 小米/OPPO/vivo必传
});
if (!nativeAd) {
console.log('不支持原生广告');
return;
}
// 监听加载事件
nativeAd.onLoad((data) => {
const adList = data.adList || [];
if (adList.length > 0) {
const adData = adList[0];
this.nativeAdData = {
adId: adData.adId,
title: adData.title,
desc: adData.desc,
imgUrlList: adData.imgUrlList,
videoUrlList: adData.videoUrlList
};
// 上报曝光
nativeAd.reportAdShow({ adId: adData.adId });
}
});
nativeAd.onError((err) => {
console.error('原生广告加载失败', err);
});
}
onAdClick() {
if (this.nativeAd) {
this.nativeAd.reportAdClick({ adId: this.nativeAdData.adId });
}
}华为/荣耀需要预加载,并且需要显示关闭按钮:
const nativeAd = QuickBox.createNativeAd({
adUnitId: 'YOUR_AD_UNIT_ID',
allowRecommend: true // 荣耀必传
});
// 华为/荣耀会自动调用 load(),但可以手动监听
if (QuickBox.isHuawei() || QuickBox.isHonor()) {
nativeAd.onLoad((data) => {
// 处理加载成功
});
}OPPO/vivo使用 preloadAd,需要 adCount 参数:
const nativeAd = QuickBox.createNativeAd({
adUnitId: 'YOUR_AD_UNIT_ID',
adCount: 1 // OPPO必传
});import { ReaderUtils } from 'quickbox';
// 获取设备信息
const deviceInfo = await QuickBox.getSystemInfo();
// 分页内容
const result = ReaderUtils.splitContentIntoPages({
deviceInfo: {
windowWidth: deviceInfo.windowWidth,
windowHeight: deviceInfo.windowHeight,
screenDensity: deviceInfo.screenDensity
},
content: ['段落1内容', '段落2内容'],
fontSize: 30,
lineHeightRatio: 2.1,
padding: 30,
topPadding: 100
});
console.log('分页结果', result.pages);
console.log('每页行数', result.linesPerPage);
console.log('每行字符数', result.charsPerLine);// 在分页内容中插入广告页
const pagesWithAd = ReaderUtils.insertAdPages(
result.pages,
'iaa广告页', // 广告页标记
0, // 第一页索引
5, // 每5页插入一个广告
true // 第一页前也插入
);const deviceInfo = await QuickBox.getSystemInfo();
const isHuaweiGroup = QuickBox.isHuaweiGroup();
const bannerStyle = ReaderUtils.calculateBannerStyle(deviceInfo, {
height: 57,
bottom: 20,
isHuaweiGroup
});
// 创建Banner广告
const bannerAd = QuickBox.createBannerAd({
adUnitId: 'YOUR_AD_UNIT_ID',
autoWidth: true, // 自动适配宽度
style: bannerStyle
});<!-- template -->
<block if="{{isHuawei || isOppo}}">
<!-- 华为/OPPO特殊UI -->
</block>
<block else>
<!-- 其他厂商UI -->
</block>// script
computed: {
isHuawei() {
return QuickBox.isHuawei();
},
isOppo() {
return QuickBox.isOppo();
},
isMi() {
return QuickBox.isXiaomi();
}
}// 根据厂商使用不同的API
if (QuickBox.isHuawei() || QuickBox.isHonor()) {
// 华为/荣耀特殊处理
await QuickBox.huaweiPay({...});
} else if (QuickBox.isXiaomi()) {
// 小米特殊处理
await QuickBox.xiaomiPay({...});
}// app.ux
import QuickBox from 'quickbox';
export default {
async onCreate() {
// 1. 配置网络请求
QuickBox.Request.configure({
baseURL: 'https://api.example.com',
baseParams: () => ({
max_app_id: this.getAppId(),
max_version: this.getVersion(),
max_brand: QuickBox.getVendorInfo().vendor
}),
onUnauthorized: async () => {
await this.handleUnauthorized();
}
});
// 2. 预加载支付配置
await this.preloadPaymentConfigs();
// 3. 检查加桌状态
const isInstalled = await QuickBox.ShortcutUtils.checkInstalled();
this.isDesktop = isInstalled;
// 4. 初始化其他功能
await this.initOtherFeatures();
},
async preloadPaymentConfigs() {
const vendor = QuickBox.getVendorInfo().vendor;
try {
if (vendor === 'huawei' || vendor === 'honor') {
this.paymentConfigs.huawei = await QuickBox.ConfigManager.getHuaweiConfig(
'https://api.example.com/app/config/getHuaweiConfig'
);
}
// ... 其他厂商
} catch (error) {
console.error('预加载支付配置失败', error);
}
}
}import QuickBox from 'quickbox';
// 获取华为Token(自动缓存)
const hwToken = await QuickBox.TokenManager.getHuaweiToken('YOUR_APPID', 'MEMBER_ID');
// 获取小米Token(自动缓存)
const miToken = await QuickBox.TokenManager.getXiaomiToken('MEMBER_ID');
// 根据厂商自动获取Token
const token = await QuickBox.TokenManager.getTokenByVendor({
huaweiAppid: 'YOUR_APPID',
xiaomiMemberId: 'MEMBER_ID'
});
// 清除Token缓存
await QuickBox.TokenManager.clearToken('hwToken_YOUR_APPID');Token管理器会自动缓存Token到内存和本地存储,避免重复请求:
- 内存缓存:快速访问,应用重启后失效
- 本地存储:持久化缓存,应用重启后仍然有效
- 过期管理:支持设置过期时间,自动清除过期Token
// app.ux
import QuickBox from 'quickbox';
export default {
async onCreate() {
// 初始化应用
await this.initApp();
// 设置应用就绪
QuickBox.AppStateManager.setReady(true);
}
}
// 其他页面
export default {
async onInit() {
// 等待应用就绪后再执行
await QuickBox.AppStateManager.waitForReady();
// 安全执行操作
const data = await QuickBox.Request.get('/api/data');
}
}// 方式1:使用 waitForReady
await QuickBox.AppStateManager.waitForReady();
const data = await QuickBox.Request.get('/api/data');
// 方式2:使用 ensureReady(推荐)
const data = await QuickBox.AppStateManager.ensureReady(async () => {
return await QuickBox.Request.get('/api/data');
});// 设置来源名称(7天后过期)
await QuickBox.SourceTracker.setSource('content_123', 'origin_name', '书城', 7);
// 设置渠道名称(7天后过期)
await QuickBox.SourceTracker.setSource('content_123', 'chl_name', '文末推荐', 7);
// 设置一级来源(90天后过期)
await QuickBox.SourceTracker.setSource('content_123', 'first_origin', '书城', 90);// 获取单个来源
const originName = await QuickBox.SourceTracker.getSource('content_123', 'origin_name');
// 获取所有来源
const sources = await QuickBox.SourceTracker.getAllSources('content_123');
// { origin_name: '书城', chl_name: '文末推荐', first_origin: '书城' }
// 检查来源是否有效(未过期)
const isValid = await QuickBox.SourceTracker.isSourceValid('content_123', 'origin_name');// 清除单个来源
await QuickBox.SourceTracker.clearSource('content_123', 'origin_name');
// 清除所有来源
await QuickBox.SourceTracker.clearSource('content_123');// 防抖:连续调用只会在指定时间后执行一次
const debouncedSearch = QuickBox.debounce((keyword) => {
console.log('搜索:', keyword);
}, 300);
// 节流:指定时间内最多执行一次
const throttledScroll = QuickBox.throttle(() => {
console.log('滚动事件');
}, 100);
// 使用示例
input.onInput((e) => {
debouncedSearch(e.value);
});
window.addEventListener('scroll', throttledScroll);// 延迟执行
await QuickBox.delay(1000); // 等待1秒
// 重试机制
const result = await QuickBox.retry(
() => QuickBox.Request.get('/api/data'),
3, // 最多重试3次
1000 // 每次重试间隔1秒
);// 格式化文件大小
QuickBox.formatFileSize(1024); // "1 KB"
QuickBox.formatFileSize(1048576); // "1 MB"
// 深拷贝
const cloned = QuickBox.deepClone(originalObject);-
原生广告:
- 小米必须使用
<ad-clickable-area>包裹点击区域 - 华为/荣耀需要预加载
- OPPO需要
adCount参数
- 小米必须使用
-
Banner广告:
- 华为宽度固定360,其他厂商750
- 使用
autoWidth: true自动适配
-
加桌功能:
- 华为/OPPO使用API方式
- 其他厂商使用组件方式
-
支付配置:
- 建议在应用启动时预加载
- 可以缓存配置避免重复请求
-
网络请求:
- 统一参数通过
baseParams配置 - 401错误会自动触发
onUnauthorized - 错误会自动显示Toast提示(可通过
showErrorToast: false关闭)
- 统一参数通过