1# 使用Web组件加载页面 2 3 4页面加载是Web组件的基本功能。根据页面加载数据来源可以分为三种常用场景,包括加载网络页面、加载本地页面、加载HTML格式的富文本数据。 5 6 7页面加载过程中,若涉及网络资源获取,需要配置[ohos.permission.INTERNET](../security/AccessToken/declare-permissions.md)网络访问权限。 8 9 10## 加载网络页面 11 12开发者可以在Web组件创建时,指定默认加载的网络页面 。在默认页面加载完成后,如果开发者需要变更此Web组件显示的网络页面,可以通过调用[loadUrl()](../reference/apis-arkweb/js-apis-webview.md#loadurl)接口加载指定的网页。 13 14 15在下面的示例中,在Web组件加载完“www\.example.com”页面后,开发者可通过loadUrl接口将此Web组件显示页面变更为“www\.example1.com”。 16 17 18 19```ts 20// xxx.ets 21import web_webview from '@ohos.web.webview'; 22import business_error from '@ohos.base'; 23 24@Entry 25@Component 26struct WebComponent { 27 webviewController: web_webview.WebviewController = new web_webview.WebviewController(); 28 29 build() { 30 Column() { 31 Button('loadUrl') 32 .onClick(() => { 33 try { 34 // 点击按钮时,通过loadUrl,跳转到www.example1.com 35 this.webviewController.loadUrl('www.example1.com'); 36 } catch (error) { 37 let e: business_error.BusinessError = error as business_error.BusinessError; 38 console.error(`ErrorCode: ${e.code}, Message: ${e.message}`); 39 } 40 }) 41 // 组件创建时,加载www.example.com 42 Web({ src: 'www.example.com', controller: this.webviewController}) 43 } 44 } 45} 46``` 47 48 49## 加载本地页面 50 51将本地页面文件放在应用的rawfile目录下,开发者可以在Web组件创建的时候指定默认加载的本地页面 ,并且加载完成后可通过调用[loadUrl()](../reference/apis-arkweb/js-apis-webview.md#loadurl)接口变更当前Web组件的页面。 52 53 54在下面的示例中展示加载本地页面文件的方法: 55 56 57- 将资源文件放置在应用的resources/rawfile目录下。 58 59 **图1** 资源文件路径 60 61  62 63 64- 应用侧代码。 65 66 ```ts 67 // xxx.ets 68 import web_webview from '@ohos.web.webview'; 69 import business_error from '@ohos.base'; 70 71 @Entry 72 @Component 73 struct WebComponent { 74 webviewController: web_webview.WebviewController = new web_webview.WebviewController(); 75 76 build() { 77 Column() { 78 Button('loadUrl') 79 .onClick(() => { 80 try { 81 // 点击按钮时,通过loadUrl,跳转到local1.html 82 this.webviewController.loadUrl($rawfile("local1.html")); 83 } catch (error) { 84 let e: business_error.BusinessError = error as business_error.BusinessError; 85 console.error(`ErrorCode: ${e.code}, Message: ${e.message}`); 86 } 87 }) 88 // 组件创建时,通过$rawfile加载本地文件local.html 89 Web({ src: $rawfile("local.html"), controller: this.webviewController }) 90 } 91 } 92 } 93 ``` 94 95 96- local.html页面代码。 97 98 ```html 99 <!-- local.html --> 100 <!DOCTYPE html> 101 <html> 102 <body> 103 <p>Hello World</p> 104 </body> 105 </html> 106 ``` 107 108 109## 加载HTML格式的文本数据 110 111Web组件可以通过[loadData()](../reference/apis-arkweb/js-apis-webview.md#loaddata)接口实现加载HTML格式的文本数据。当开发者不需要加载整个页面,只需要显示一些页面片段时,可通过此功能来快速加载页面。 112 113 114 115```ts 116// xxx.ets 117import web_webview from '@ohos.web.webview'; 118import business_error from '@ohos.base'; 119 120@Entry 121@Component 122struct WebComponent { 123 controller: web_webview.WebviewController = new web_webview.WebviewController(); 124 125 build() { 126 Column() { 127 Button('loadData') 128 .onClick(() => { 129 try { 130 // 点击按钮时,通过loadData,加载HTML格式的文本数据 131 this.controller.loadData( 132 "<html><body bgcolor=\"white\">Source:<pre>source</pre></body></html>", 133 "text/html", 134 "UTF-8" 135 ); 136 } catch (error) { 137 let e: business_error.BusinessError = error as business_error.BusinessError; 138 console.error(`ErrorCode: ${e.code}, Message: ${e.message}`); 139 } 140 }) 141 // 组件创建时,加载www.example.com 142 Web({ src: 'www.example.com', controller: this.controller }) 143 } 144 } 145} 146``` 147 148## 动态创建web组件 149支持命令式创建Web组件,这种方式创建的组件不会立即挂载到组件树,即不会对用户呈现(组件状态为Hidden和InActive),开发者可以在后续使用中按需动态挂载。后台启动的Web实例不建议超过200个。 150 151```ts 152// 载体Ability 153// EntryAbility.ets 154import {createNWeb} from "../pages/common" 155onWindowStageCreate(windowStage: window.WindowStage): void { 156 windowStage.loadContent('pages/Index', (err, data) => { 157 // 创建Web动态组件(需传入UIContext),loadContent之后的任意时机均可创建 158 createNWeb("https://www.example.com", windowStage.getMainWindowSync().getUIContext()); 159 if (err.code) { 160 return; 161 } 162 }); 163} 164``` 165```ts 166// 创建NodeController 167// common.ets 168import { UIContext } from '@ohos.arkui.UIContext'; 169import web_webview from '@ohos.web.webview' 170import { NodeController, BuilderNode, Size, FrameNode } from '@ohos.arkui.node'; 171// @Builder中为动态组件的具体组件内容 172// Data为入参封装类 173class Data{ 174 url: string = "https://www.example.com"; 175 controller: WebviewController = new web_webview.WebviewController(); 176} 177 178@Builder 179function WebBuilder(data:Data) { 180 Column() { 181 Web({ src: data.url, controller: data.controller }) 182 .width("100%") 183 .height("100%") 184 } 185} 186 187let wrap = wrapBuilder<Data[]>(WebBuilder); 188 189// 用于控制和反馈对应的NodeContainer上的节点的行为,需要与NodeContainer一起使用 190export class myNodeController extends NodeController { 191 private rootnode: BuilderNode<Data[]> | null = null; 192 // 必须要重写的方法,用于构建节点数、返回节点挂载在对应NodeContainer中 193 // 在对应NodeContainer创建的时候调用、或者通过rebuild方法调用刷新 194 makeNode(uiContext: UIContext): FrameNode | null { 195 console.log(" uicontext is undifined : "+ (uiContext === undefined)); 196 if (this.rootnode != null) { 197 // 返回FrameNode节点 198 return this.rootnode.getFrameNode(); 199 } 200 // 返回null控制动态组件脱离绑定节点 201 return null; 202 } 203 // 当布局大小发生变化时进行回调 204 aboutToResize(size: Size) { 205 console.log("aboutToResize width : " + size.width + " height : " + size.height ) 206 } 207 208 // 当controller对应的NodeContainer在Appear的时候进行回调 209 aboutToAppear() { 210 console.log("aboutToAppear") 211 } 212 213 // 当controller对应的NodeContainer在Disappear的时候进行回调 214 aboutToDisappear() { 215 console.log("aboutToDisappear") 216 } 217 218 // 此函数为自定义函数,可作为初始化函数使用 219 // 通过UIContext初始化BuilderNode,再通过BuilderNode中的build接口初始化@Builder中的内容 220 initWeb(url:string, uiContext:UIContext, control:WebviewController) { 221 if(this.rootnode != null) 222 { 223 return; 224 } 225 // 创建节点,需要uiContext 226 this.rootnode = new BuilderNode(uiContext) 227 // 创建动态Web组件 228 this.rootnode.build(wrap, { url:url, controller:control }) 229 } 230} 231 // 创建Map保存所需要的NodeController 232let NodeMap:Map<string, myNodeController | undefined> = new Map(); 233// 创建Map保存所需要的WebViewController 234let controllerMap:Map<string, WebviewController | undefined> = new Map(); 235 236// 初始化需要UIContext 需在Ability获取 237export const createNWeb = (url: string, uiContext: UIContext) => { 238 // 创建NodeController 239 let baseNode = new myNodeController(); 240 let controller = new web_webview.WebviewController() ; 241 // 初始化自定义web组件 242 baseNode.initWeb(url, uiContext, controller); 243 controllerMap.set(url, controller) 244 NodeMap.set(url, baseNode); 245} 246// 自定义获取NodeController接口 247export const getNWeb = (url : string) : myNodeController | undefined => { 248 return NodeMap.get(url); 249} 250``` 251```ts 252// 使用NodeController的Page页 253// Index.ets 254import {createNWeb, getNWeb} from "./common" 255@Entry 256@Component 257struct Index { 258 build() { 259 Row() { 260 Column() { 261 // NodeContainer用于与NodeController节点绑定,rebuild会触发makeNode 262 // Page页通过NodeContainer接口绑定NodeController,实现动态组件页面显示 263 NodeContainer(getNWeb("https://www.example.com")) 264 .height("90%") 265 .width("100%") 266 } 267 .width('100%') 268 } 269 .height('100%') 270 } 271} 272 273``` 274## 相关实例 275 276针对Web组件开发,有以下相关实例可供参考: 277 278- [浏览器(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Web/Browser)