Harmony应用开发——Web组件实现文章内容显示

这篇具有很好参考价值的文章主要介绍了Harmony应用开发——Web组件实现文章内容显示。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、WEB组件

        Web组件用于在应用程序中显示Web页面内容,为开发者提供页面加载、页面交互、页面调试等能力。

  • 页面加载:Web组件提供基础的前端页面加载的能力,包括加载网络页面、本地页面、Html格式文本数据。
  • 页面交互:Web组件提供丰富的页面交互的方式,包括:设置前端页面深色模式,新窗口中加载页面,位置权限管理,Cookie管理,应用侧使用前端页面JavaScript等能力。
  • 页面调试:Web组件支持使用Devtools工具调试前端页面。

详情请访问HarmonyOS官方文档

二、需求描述

        我目前正在做个人博客的项目,项目中包含文章查看的功能。由于服务器保存的文章内容数据为html格式的文本,所以我首先想到的是利用Web组件引入写好的本地html资源。既能够正常显示html页面,也能为文章中的代码块实现高亮功能。

Harmony应用开发——Web组件实现文章内容显示,前端,harmonyos,typescript

三、实现步骤

  1. 在rawfile下创建html文件并编写基本结构,然后保存到指定目录。
    <!doctype html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport"
              content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>菠萝狂人的分享园</title>
    </head>
    
    <body>
        // 文章内容
        <div id="content"></div>
        <script>
            // ...
        </script>
    </body>
    
    </html>
  2. 在html中引入highlight.js库(用于代码高亮)
    <!doctype html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport"
              content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>菠萝狂人的分享园</title>
        <link rel="stylesheet" href="./style/default.min.css">
    </head>
    
    <body>
    <div id="content"></div>
    <script src="./script/highlight.min.js"></script>
    <script>
        // ...
    </script>
    </body>
    
    </html>
  3. 在html中编写需要的全局函数
    <!doctype html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport"
              content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>菠萝狂人的分享园</title>
        <link rel="stylesheet" href="./style/default.min.css">
    </head>
    
    <body>
    <div id="content"></div>
    <script src="./script/highlight.min.js"></script>
    <script>
    
            var el = document.getElementById("content")
            function setContent(content) {
                el.innerHTML = content
            }
    </script>
    </body>
    
    </html>
  4. 在Article.ets中声明WEB组件并加载html文件
    // 文章内容
    Web({
        src: $rawfile("web/index.html"),
        controller: this.webviewController
    })
        .javaScriptAccess(true)
        .fileAccess(true)
        .imageAccess(true)
        .domStorageAccess(true)
        .onPageEnd(() => {})

    在以上的代码中,通过创建Web组件并设置src为html文件路径从而实现html页面的加载。代码中还涉及了其它的Api及配置。controller的值为Web组件的控制器:WebviewController,本项目中通过调用controller.runJavaScript()实现将文章数据渲染到页面上。javaScriptAccess()用于设置是否允许执行脚本,默认为允许执行。fileAccess()用于设置是否开启应用中文件系统的访问,默认启用。domStorageAccess()用于设置是否开启文档对象模型存储接口权限,默认未开启。imageAccess()用于设置是否允许自动加载图片资源,默认允许。onPageEnd()为监听页面加载完毕后执行

  5. 获取文章数据后通过WEB组件的runJavaScript()执行指定函数
    import TopBar from "../views/TopBar"
    import { Theme } from '../common/utils/theme'
    import LazyView from "../components/LazyView"
    import articleApi from "../common/apis/article"
    import router from '@ohos.router'
    import { ApiResult } from '../common/utils/http/request'
    import { ArticleContent, ArticleTag } from '../common/models/Article'
    import { parseTime } from "../common/utils/utils"
    import webview from '@ohos.web.webview'
    
    @Entry
    @Component
    struct Article {
      private params = router.getParams()
      @Provide @Watch("onThemeChange") theme: Theme = this.params["theme"]
      @State loading: boolean = true
      @State isError: boolean = false
      @State toggleLoad: boolean = false
      private content: ArticleContent = null
      private webviewController: WebviewController = new webview.WebviewController()
    
      @Builder ArticleContent() {
        //   content
        Column() {
          //   文章信息
          Column() {
            //   文章标题
            Text(this.content.title)
              .fontSize(14).width("100%")
              .fontColor(this.theme.fontColor)
            //   文章标签和创建时间
            Row() {
              // 标签
              Row({ space: 10 }) {
                ForEach(this.content.tags, (tag: ArticleTag) => {
                  Text(tag.name)
                    .fontColor(0xFFFFFF)
                    .padding(4)
                    .borderRadius(4)
                    .backgroundColor(this.theme.primary)
                    .fontSize(10)
                }, (tag: ArticleTag) => tag.id + "")
              }
              // 创建时间
              Text(parseTime(this.content.create_time))
                .fontSize(10)
                .fontColor(0xAFAFAF)
            }.justifyContent(FlexAlign.SpaceBetween).width("100%")
          }
          .padding({
            top: 10,
            left: 10
          })
          .width("100%")
    
          Column() {
            Scroll() {
              // 文章内容
              Web({
                src: $rawfile("web/index.html"),
                controller: this.webviewController
              })
                .javaScriptAccess(true)
                .fileAccess(true)
                .imageAccess(true)
                .domStorageAccess(true)
                .onPageEnd(() => {
                  this.webviewController.runJavaScript(`setContent(\`${this.content.content}\`)`)
                })
                .backgroundColor(this.theme.overlay)
            }
            .width("100%")
          }
          .width("100%")
        }
        .width("100%")
        .backgroundColor(this.theme.overlay)
        .padding(10)
      }
    
      build() {
        Column() {
          TopBar({
            backButton: true
          })
          if (this.loading) {
              Text("加载中...")  
          } else {
              if (this.isError) {
                  Column() {
                      Text("文章加载出错")
                      Button(){
                          Text("重试")
                      }
                      .onClick(this.getContentHandle.bind(this))
                  }
              } else {
                  this.ArticleContent()
              }
          }
        }
        .height("100%")
        .width("100%")
        .backgroundColor(this.theme.bgColor)
      }
    
      private getContentHandle() {
        this.loading = true
        this.isError = false
        articleApi.queryContentHandle(this.params["id"]).then((response: ApiResult<ArticleContent>) => {
          if (response.status === 200) {
            this.content = response.data.items[0]
          } else {
            this.isError = true
          }
        })
          .catch((e) => {
            this.isError = true
          })
          .finally(() => this.loading = false)
      }
    
      aboutToAppear() {
        this.getContentHandle()
      }
    }
    
  6. 为代码块添加高亮功能
    <!doctype html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport"
              content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>菠萝狂人的分享园</title>
        <link rel="stylesheet" href="./style/default.min.css">
        <link rel="stylesheet" href="./style/main.css">
    </head>
    
    <body>
    <div id="content"></div>
    <script src="./script/highlight.min.js"></script>
    <script>
            var languageName = {
                javascript: "javascript.min.js",
                css: "css.min.js",
                markup: "xml.min.js"
            }
            var el = document.getElementById("content")
            function setContent(content) {
                el.innerHTML = content
                try {
                    var languages = content.match(/(?<=\<\w+\sclas{2}="language-)\w+/g)
                    if (languages) {
                        var loaded = {}
                        for (var i = 0; i < languages.length; i++) {
                            var language = languages[i]
                            if (loaded[language] || !languageName[language]) continue
                            var script = document.createElement("script")
                            script.src = "./script/languages/" + languageName[language]
                            document.body.appendChild(script)
                            loaded[language] = true
                        }
                    }
                } catch (e) {
                    document.write(e)
                }
                setTimeout(function () { hljs.highlightAll() }, 600)
            }
    </script>
    </body>
    
    </html>

    在以上的代码,通过引入highlight.js并封装setContent函数,参数content为html格式的文章数据。由于hightlight.js实现某个语言的代码高亮需要单独引入对应的文件,所以我通过正则表达式匹配出代码块的语言从而实现按需加载,避免没必要的js文件的引入。我的项目中文章数据里的代码块是通过给标签添加language-xxxx类名标注该代码块的语言。例如:javaScript代码块就为<pre class="language-javascript">...</pre>。所以就得出以下正则表达式:/(?<=\<\w+\sclas{2}="language-)\w+/g,通过这个正则表达式就可以匹配文章中所有代码块的语言。然后通过声明一个对象,属性为语言名称,值为该语言对应的文件名。最后遍历匹配结果,如果还没有引入该语言的js文件,就创建script并插入到页面中。这样就实现了按需加载

四、效果展示

2024-01-04 23-04-26

五、总结

        今天我简单的分享了我在项目中如何使用Web组件来实现html的加载并通过runJavaScript将文章数据渲染到页面上。文章来源地址https://www.toymoban.com/news/detail-781252.html

到了这里,关于Harmony应用开发——Web组件实现文章内容显示的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 鸿蒙Harmony应用开发—ArkTS声明式开发(通用属性:组件内容模糊)

    为当前组件添加内容模糊效果。 说明: 从API Version 10开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。 foregroundBlurStyle(value: BlurStyle, options?: ForegroundBlurStyleOptions) 为当前组件提供内容模糊能力。 系统能力:  SystemCapability.ArkUI.ArkUI.Full 参数: 参数

    2024年03月09日
    浏览(55)
  • 鸿蒙Harmony应用开发—ArkTS声明式开发(容器组件:UIExtensionComponent (系统接口))

    UIExtensionComponent用于支持在本页面内嵌入其他应用提供的UI。展示的内容在另外一个进程中运行,本应用并不参与其中的布局和渲染。 通常用于有进程隔离诉求的模块化开发场景。 说明: 该组件从API Version 10开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的

    2024年04月13日
    浏览(47)
  • 鸿蒙Harmony应用开发—ArkTS声明式开发(基础手势:Web)下篇

    onRequestSelected onRequestSelected(callback: () = void) 当Web组件获得焦点时触发该回调。 示例: onScreenCaptureRequest10+ onScreenCaptureRequest(callback: (event?: { handler: ScreenCaptureHandler }) = void) 通知收到屏幕捕获请求。 参数: 参数名 参数类型 参数描述 handler ScreenCaptureHandler 通知Web组件用户操作行

    2024年04月09日
    浏览(48)
  • 【鸿蒙应用ArkTS开发系列】- Web组件使用讲解

    目录 一、Web组件介绍 二、创建组件 权限列表 三、设置样式和属性 四、添加事件和方法 五、访问本地Html 1、本地html文件创建 2、本地html文件加载 2、JS对象注入,Html使用JS对象调用客户端方法 3、客户端调用本地Html网页中的JS方法 使用鸿蒙的ArkUI框架开发鸿蒙应用的时候,官

    2024年02月07日
    浏览(50)
  • 华为Harmony应用开发初探

    HarmonyOS是一款面向万物互联时代的、全新的分布式操作系统。在传统的单设备系统能力基础上,HarmonyOS提出了基于同一套系统能力、适配多种终端形态的分布式理念,能够支持手机、平板、智能穿戴、智慧屏、车机等多种终端设备,提供全场景(移动办公、运动健康、社交通

    2024年02月15日
    浏览(52)
  • Harmony 应用开发的知识储备

      这里先说明一点,如果你对Android应用开发很熟悉,那么做Harmony应用开发也可以驾轻就熟,只不过在此之前你需要知道一些关于Harmony应用开发的相关知识。   那么问题就来了,我为什么会知道这些相关的知识点呢?因为踩过一遍坑了,说多了都是泪,唯有文字记录,当

    2024年02月04日
    浏览(38)
  • 鸿蒙HarmonyOS应用开发能找到工作么?_harmony os 应用开发前景

    四、如何学习鸿蒙HarmonyOS应用开发技术? 为了能够帮助大家快速掌握鸿蒙(Harmony NEXT)应用开发技术知识。 首先得是开发语言 ArkTS,这个尤为重要,然后就是ArkUI声明式UI开发、Stage模型、网络/数据库管理、分布式应用开发、进程间通信与线程间通信技术、OpenHarmony多媒体技

    2024年04月27日
    浏览(40)
  • 鸿蒙Harmony应用开发—ArkTS声明式开发(基础手势:CalendarPicker)

    日历选择器组件,提供下拉日历弹窗,可以让用户选择日期。 说明: 该组件从API Version 10开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。 无 CalendarPicker(options?: CalendarOptions) 日历选择器。 系统能力:  SystemCapability.ArkUI.ArkUI.Full 参数: 参数名

    2024年03月09日
    浏览(43)
  • 鸿蒙Harmony应用开发—ArkTS声明式开发(基础手势:Search)

    搜索框组件,适用于浏览器的搜索内容输入框等应用场景。 说明: 该组件从API Version 8开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。 无 Search(options?: { value?: string, placeholder?: ResourceStr, icon?: string, controller?: SearchController }) 参数: 参数名 参数类型

    2024年03月24日
    浏览(56)
  • 鸿蒙Harmony应用开发—ArkTS声明式开发(自定义事件分发)

    ArkUI在处理触屏事件时,会在触屏事件触发前进行按压点和组件区域的触摸测试,来收集需要响应触屏事件的组件,再基于触摸测试结果分发相应的触屏事件。在父节点,开发者可以通过onChildTouchTest决定如何让子节点去做触摸测试,影响子组件的触摸测试,最终影响后续的触

    2024年04月14日
    浏览(56)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包