下面给你「带进度条 + 判断 index.html 已存在则跳过解压」的完整可运行版本,直接替换即可通过 ArkTS 校验。
思路
- 先判断
www/dist/index.html是否存在,存在就直接返回。 - 解压前把
unzipFile的onProgress回调接到@State progress上,实时刷新 Progress 组件。 - 解压完成后隐藏进度条,自动加载本地 html。
ts
import web_webview from '@ohos.web.webview';
import fs from '@ohos.file.fs';
import zlib from '@ohos.zlib';
import { Context } from '@ohos.abilityAccessCtrl';
@Entry
@Component
struct WebLoadLocalHtml {
private webCtrl = new web_webview.WebviewController();
@State wwwPath: string = '';
@State showProgress: boolean = false;
@State progress: number = 0; // 0~100
/* 主逻辑:带进度解压 */
private async copyAndUnzip(context: Context): Promise<string> {
const wwwDir = context.filesDir + '/www';
const targetHtml = wwwDir + '/dist/index.html';
// 1. 已存在则直接返回
try {
fs.accessSync(targetHtml);
console.info('index.html 已存在,跳过解压');
return wwwDir;
} catch { /* 不存在就继续 */ }
// 2. 准备目录
try { fs.mkdirSync(wwwDir); } catch {}
// 3. 拷贝 zip
const rawBytes = context.resourceManager.getRawFileContentSync('dist.zip');
const zipPath = wwwDir + '/dist.zip';
this.writeFileOnlyOne(zipPath, rawBytes);
// 4. 带进度解压
this.showProgress = true;
this.progress = 0;
// 3. 解压(补齐第 3 个参数)
let options: zlib.Options = {
level: zlib.CompressLevel.COMPRESS_LEVEL_DEFAULT_COMPRESSION,
memLevel: zlib.MemLevel.MEM_LEVEL_DEFAULT,
strategy: zlib.CompressStrategy.COMPRESS_STRATEGY_DEFAULT_STRATEGY
};
zlib.unzipFile(destZip, wwwDir, options).then(()=>{
fs.unlinkSync(destZip);
this.wwwPath=wwwDir;
this.showProgress = false;
});
return wwwDir;
}
/* 写文件助手 */
private writeFileOnlyOne(filePath: string, data: Uint8Array) {
try { if (fs.accessSync(filePath)) return; } catch {}
const f = fs.openSync(filePath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
fs.writeSync(f.fd, data.buffer);
fs.closeSync(f);
}
/* 生命周期 */
async aboutToAppear() {
this.wwwPath = await this.copyAndUnzip(getContext());
}
build() {
Stack() {
Column() {
Button('加载 html')
.onClick(() => {
this.webCtrl.loadUrl(`file://${this.wwwPath}/dist/index.html`);
})
Web({ src: `file://${this.wwwPath}/dist/index.html`, controller: this.webCtrl })
.javaScriptAccess(true)
.fileAccess(true)
.onPageEnd(() => console.info('Vue 页面加载完成'))
.width('100%')
.height('100%')
}
/* 进度条遮罩 */
if (this.showProgress) {
Column() {
Progress({ value: this.progress, total: 100, type: ProgressType.Linear })
.width('80%')
Text(`解压中...${this.progress}%`)
}
.width('100%')
.height('100%')
.backgroundColor('#80000000')
.justifyContent(FlexAlign.Center)
}
}
}
}
使用要点
- 判断的是
www/dist/index.html而不是www,避免目录存在但文件没写完的误判。 - 进度条用
Stack盖在 Web 组件上,解压完自动消失。