OpenHarmony JS Demo开发讲解

news2025/1/18 19:02:08

项目结构

打开entry→src→main→js,工程的开发目录如图所示

其中,

  • i18n文件夹:用于存放配置不同语言场景的资源,比如应用文本词条,图片路径等资源。en-US.json文件定义了在英文模式下页面显示的变量内容,zh-CN.json文件定义了中文模式下的页面内容。
  • pages文件夹用于存放多个页面,每个页面由hml、css和js文件组成。
    • index.hml文件:定义了index页面的布局,index页面中用到的组件,以及这些组件的层级关系。
    • index.css文件:定义了index页面的样式。
    • index.js文件:定义了index页面的业务逻辑,比如数据绑定、事件处理等。
  • app.js文件:进行全局的逻辑文件和应用生命周期管理。
  • resources文件夹:用于存放开发资源文件的目录。包括图片、音视频等资源文件。
  • config.json文件:应用配置文件。用于声明应用的Ability信息,及应用所需的权限等信息。

JS FA

可将该FA一共分成三个部分:图片区、标题区、描述区。根据此分区,根节点的子节点应按列排列。 图片区和描述区分别使用 swiper组件和text组件实现。标题区由两个部分组成,以行来排列,其中第一部分由两个text组件组成,分别为商品名称和商品标语,以列排列。第二部分由image组件和text组件组成,分别为代表收藏功能的星号和代表收藏次数的数字,以行排列,如图所示。

首先构建FA基础布局。其中,实现图片区域通常用image组件来实现,由于需要左右滑动图片,因此在image外层加入swiper滑动容器,swiper容器提供了切换子组件显示的能力。 标题区和描述区采用了最常用的基础组件text,text组件用于展示文本,文本内容需要写在标签内容区。要将页面的基本元素组装在一起,需要使用容器组件,如上述swiper容器。在页面布局中常用到三种容器组件,分别是div、list和tabs。在页面结构相对简单时,可以直接用div作为容器,因为div作为单纯的布局容器,使用起来更为方便,可以支持多种子组件。 在index.hml文件中,实现基础布局,具体代码如下所示:

<div class="container">
    <swiper class="swiper-style">
        <image src="/common/Phone_00.jpg" class="image-mode"></image>
        <image src="/common/Phone_01.jpg" class="image-mode"></image>
        <image src="/common/Phone_02.jpg" class="image-mode"></image>
        <image src="/common/Phone_03.jpg" class="image-mode"></image>
    </swiper>
    <div class="title-section">
        <div class="phone-title">
            <text class="phone-name">
                HUAWEI
            </text>
            <text class="phone-definition">
                Thinking Possibilities
            </text>
        </div>
        <div class="favorite-image">
            <image src="{{unFavoriteImage}}" class="image-size"οnclick="favorite"></image>
        </div>
        <div class="favorite-count">
            <text>{{number}}
            </text>
        </div>
    </div>
    <div class="description-first-paragraph">
        <text class="description">{{descriptionFirstParagraph}}
        </text>
    </div>
    <div class="description-second-paragraph">
        <text class="description">{{descriptionSecondParagraph}}
        </text>
    </div>
</div>

在index.hml中,为每个组件和容器都定义了一个class=“***”的样式,需要在css文件中依次对样式进行构建。如本例,在index.css文件中,需要设定的样式主要有:flex-direction用于设置子组件容器的排列方式,paddind用于设置内边距,font-size用于设置字体大小,以及swiper组件的一些私有属性,如indicator-color用于设置导航点指示器的填充颜色,indicator-selected-color用于设置导航点指示器选中的颜色,indicator-size用于设置导航点指示器的直径大小等。具体代码如下所示:

.container {
    flex-direction: column;
}
.swiper-style {
    height: 700px;
    indicator-color: #4682b4;
    indicator-selected-color: #ffffff;
    indicator-size: 20px;
}
.title-section {
    flex-direction: row;
    height: 150px;
}
.phone-title {
    align-items:flex-start;
    flex-direction: column;
    padding-left: 60px;
    padding-right: 160px;
    padding-top: 50px;
}
.phone-name {
    font-size: 50px;
    color: #000000;
}
.phone-definition {
    font-size: 30px;
    color: #7A787D;
}
.favorite-image {
    padding-left: 70px;
    padding-top: 50px;
}
.favorite-count {
    padding-top: 60px;
    padding-left: 10px;
}
.image-size {
    object-fit: contain;
    height: 60px;
    width: 60px;
}
.description-first-paragraph {
    padding-left: 60px;
    padding-top: 50px;
    padding-right: 60px;
}
.description-second-paragraph {
    padding-left: 60px;
    padding-top: 30px;
    padding-right: 60px;
}
.description {
    color: #7A787D;
}
.image-mode {
    object-fit: contain;
}

在index.js用于构建页面逻辑,对图片资源进行赋值,并通过添加交互实现收藏功能。收藏按钮通过一个div组件关联click事件实现。click事件作为一个函数定义在index.js文件中,可以更改isFavorite的状态,从而更新显示的image组件和text组件。index.js中代码如下所示:

export default {
    data: {
        unFavoriteImage: "/common/unfavorite.png",
        isFavorite: false,
        number: 20,
        descriptionFirstParagraph:"The breakthrough of visual boundaries, the exploration of photography and videography, the liberation of power and speed, and the innovation of interaction are now ready to be discovered. Embrace the future with new possibilities.",
        descriptionSecondParagraph: "Lighting up infinite possibilities. The quad camera of HUAWEI is embraced by the halo ring. It is a perfect fusion of reflection and refraction. Still Mate, but a new icon.",
    },
    favorite() {
        var tempTotal;
        if (!this.isFavorite) {
            this.unFavoriteImage = "/common/favorite.png";
            tempTotal = this.number + 1;
        } else {
            this.unFavoriteImage = "/common/unfavorite.png";
            tempTotal = this.number -1;
        }
        this.number = tempTotal;
        this.isFavorite = !this.isFavorite;
    }
}

常用组件

根据组件的功能,可以将组件分为以下四大类

组件类型主要组件
基础组件text、image、progress、rating、span、marquee、image-animator、divider、search、menu、chart
容器组件div、list、list-item、stack、swiper、tabs、tab-bar、tab-content、popup、list-item-group、refresh、dialog
媒体组件video
画布组件canvas

基础组件-Button

Button是实现用户交互最常用的组件,可用于触发JS中的函数。可以使用JS提供的各种按钮(包括胶囊按钮、圆形按钮、文本按钮、弧形按钮、下载按钮)来实现许多有趣的功能。

<!-- index.hml定义多种按钮 -->
<div class="div-button">
    <button class="button" type="capsule" value="胶囊按钮"></button>
    <button class="button circle" type="circle" icon="common/logo.png"></button>
    <button class="button text" type="text">文本按钮</button>
    <button class="button download" type="download" id="download-btn"
            onClick="setProgress">{{downloadText}}</button>
    <button class="button" type="capsule" waiting="true">载入中...</button>
    <button class="button" type="arc">弧形按钮</button>
</div>

上述下载按钮的onClick属性绑定到了js文件中的setProgress函数中,js文件的代码如下所示

export default {
    data: {
        progress: 5,
        downloadText: "下载"
    },
    setProgress(e) {
        this.progress += 10;    //每次点击增加10%的进度
        this.downloadText = this.progress + "%";
        if (this.progress >= 100) {
            this.downloadText = "完成";   //到达100%时显示完成
        }
    }
}

实现效果如下:

List组件

List组件常用于呈现多行连续同类的数据。List列表组件包含两类子组件,分别是list-item列表项和list-item-group列表项组。这里详细讲解一下list-item-group列表项组。 list-item-group是一个具有折叠效果list列表,配合list-item使用,以list-item-group中的第一个list-item作为分类标准,以下都折叠进分类中,点击具有折叠和扩展的效果。代码如下所示:

<!-- index.hml -->
<div class="container">
    <list>
        <list-item-group>
            <list-item class="item_style"><text class="big_size">水果</text></list-item>
            <list-item><text class="font_size">苹果</text></list-item>
            <list-item><text class="font_size">香蕉</text></list-item>
        </list-item-group>
        <list-item-group>
            <list-item class="item_style"><text class="big_size">饮料</text></list-item>
            <list-item><text class="font_size">可乐</text></list-item>
            <list-item><text class="font_size">咖啡</text></list-item>
        </list-item-group>
        <list-item-group>
            <list-item class="item_style"><text class="big_size">零食</text></list-item>
            <list-item><text class="font_size">薯片</text></list-item>
            <list-item><text class="font_size">锅巴</text></list-item>
        </list-item-group>
    </list>
</div>
.item_style {
    background-color: pink;
}
.big_size {
    font-size: 50px;
}

运行上述代码,结果如图所示,实现了一个具有折叠效果的列表

自定义组件

自定义组件是用户根据业务需求,将已有的组件组合起来,封装成新的组件,并作为新组件可以在工程中被多次调用,从而提高代码的可读性和可扩展性。自定义组件通过element引入到宿主页面,使用方法的示例代码如下所示

<element name="comp" src="../comp.hml"></element>
<div>
    <comp prop1='xxxx' @child1="bindParentVmMethod"></comp>
</div>
  • name属性指定自定义组件名称(非必填,若不填组件名称则为hml文件名)。src属性指自定义组件hml文件路径,为了准确定位到该组件位置,src属性内容必须要填写,需要注意的是,src路径中"../"代表上一级目录索引。
  • prop属性用于组件之间的通信,可以通过方式传递给组件;名称必须用小写。
  • 事件绑定:自定义组件中绑定子组件事件使用(on或@)child1语法,子组件中通过this.$emit('child1', { params: '传递参数' })触发事件并进行传值,父组件执行bindParentVmMe- thod方法并接收子组件传递的参数。 下面创建一个自定义组件,并在父组件中引入自定义组件的事件响应。首先在page文件夹中新建自定义组件目录comp,同时创建自定义组件的基础htm、css和js文件,代码如下所示
<div class="item">
    <text class="title_style">{{title}}</text>
    <text class="text-style" οnclick="childClicked">点击这里查看隐藏文本</text>
    <text class="text-style" if="{{showword}}">hello world</text>
</div>
.item {
    width: 700px;
    flex-direction: column;
    height: 300px;
    align-items: center;
    margin-top: 100px;
}
.text-style {
    font-weight: 500;
    font-family: Courier;
    font-size: 40px;
}
export default {
    props: {
        title: {
            default: 'title'
        },
    },
    data: {
        showword: false,
    },
    childClicked () {
        this.$emit('eventType1', {text: "收到子组件参数"});
        this.showword = !this.showword;
    },
}

上述代码新创建了一个comp自定义组件,组件中设置了一个具有点击属性的文本内容,该点击效果会将自定义组件的数据传递给父组件,并将show值从初始化的false转为true,即显示hello world文本。 在父组件中通过element引入自定义组件,代码如下所示

<element name="comp" src="../comp/comp.hml"></element>
<div class="container">
    <text>父组件:{{text}}</text>
    <comp title="自定义组件" @event-type1="textClicked"></comp>
</div>
.container {
    background-color: #f8f8ff;
    flex: 1;
    flex-direction: column;
    align-content: center;
}
export default {
    data: {
        text: "开始"
    },
    textClicked (clicked) {
        this.text = clicked.detail.text;
    },
}

本示例中父组件通过添加自定义属性向子组件传递了名为title的参数,自定义子组件在props中接收,自定义组件可以通过props声明属性,父组件通过设置的属性向子组件传递参数,注意在命名prop时需要使用camelCase即驼峰式命名法,在外部父组件传递参数时需要使用kebab-case即用短横线分割命名,例如在上面示例代码中属性eventType1在父组件引用时需要转换为event-type1。子组件也通过事件绑定向上传递了参数text,父组件接收时通过clicked.detail获取数据。

父子组件之间的数据传输是单向的,一般的只能从父组件传递给子组件,而子组件如果需要向上传递必须绑定事件,通过事件的$emit来传输。子组件获取来自父组件数据后,子组件不能直接修改父组件传递下来的值,可以通过将props传入的值用data接收后作为默认值,然后在对data的值进行修改。 如果需要观察组件中属性的变化,可以通过$watch方法增加属性变化回调。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/470340.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java 泛型为什么设计成是可以擦除的

Java 泛型是 Java 5 引入的一种类型安全的编程机制&#xff0c;它允许在编译时指定泛型类型参数&#xff0c;从而提高代码的类型安全性和可读性。然而&#xff0c;Java 泛型的实现方式是通过类型擦除来实现的&#xff0c;这也引发了一些争议。本文将介绍 Java 泛型为什么设计成…

2023年某科技公司前端开发初级岗的面试笔试真题(含选择题答案、问答题解析、机试题源码)

📚关于该专栏: 该专栏的发布内容是前端面试中笔试部分真题、答卷类、机试等等的题目,题目类型包括逻辑题、算法题、选择题、问答题等等,除了内容的分享,还有解析和答案。真实来自某些互联网公司,坐标广东广州。 🔥🔥🔥 持 续 更 新 🔥🔥🔥 😉专栏博主: 黛…

HCIP-7.1交换机ARP、VLAN之间的三层通信技术学习

交换机ARP、VLAN之间的三层通信技术学习 1、ARP1.1、 地址解析过程1.2、ARP报文格式1.3、ARP表项1.4、免费ARP1.5、 VLAN间ARP代理1.5.1、解决同网段&#xff0c;不同广播域内主机互通问题&#xff1b;1.5.2、解决同网段&#xff0c;不同VLAN之间主机互通问题。1.5.3、解决同网…

Ignore insecure directories and continue [y] or abort compinit [n]?

问题&#xff1a; 在Mac终端中使用Zsh作为默认shell时&#xff0c;有时会弹出以下提示信息&#xff1a; Ignore insecure directories and continue [y] or abort compinit [n]? 这个提示出现的原因是因为Zsh在加载时会检查所有的目录是否安全&#xff0c;并拒绝加载不安全的…

【LeetCode: 62. 不同路径 | 暴力递归=>记忆化搜索=>动态规划 】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

卡尔曼滤波器简介——概述

关于卡尔曼滤波器 大多数现代系统都有许多传感器&#xff0c;可以根据一系列测量来估计隐藏&#xff08;未知&#xff09;状态。例如&#xff0c;GPS接收器提供位置和速度估计&#xff0c;其中位置和速度是隐藏状态&#xff0c;卫星信号到达的差分时间是测量值。 跟踪和控制系统…

ChatGPT的进化版?AutoGPT怎么用

AutoGPT是什么 首选给大家介绍&#xff0c;ChatGPT与AutoGPT的区别 目前AutoGPT被称为最接近AGI的人工智能&#xff0c;它是ChatGPT的进化版&#xff1f; “ChatGPT” 只能提供2021年9月之前的信息&#xff0c;所以你问它告诉我今天的天气&#xff0c;它回答不了 “AutoGPT” …

AutoGPT不靠谱,微软推出升级版!可编辑自主规划过程

夕小瑶科技说 原创 作者 | iven 火遍全网的AutoGPT[1]在Github收藏量突破十万。这种自我规划、自我执行的智能体首次关注人工智能模型内部的自我调整与优化。 但是有不少网友发现&#xff0c;AutoGPT的表现不稳定&#xff0c;死循环是最常见的现象。此外&#xff0c;AutoGPT执…

输入指令为±10V或4~20mA型伺服阀控制器

工作电压 19~35 VDC&#xff08;常规24VDC&#xff09; 最大功率消耗 &#xff1c;25VA 空载电流 ≤100mA&#xff08;24V&#xff09; 差分信号输入 0~10 V&#xff0c;输入阻抗≥100KΩ 4~20 mA&#xff0c;输入阻抗100Ω &#xff08;出厂前需指定&#xff0c;现场不可…

免费的ERP系统哪个好?这款让管理更高效

阅读本文你将了解&#xff1a;ERP是什么&#xff1f;解决什么问题&#xff1f;ERP选型的参考维度&#xff1f;零代码ERP系统解决哪些场景问题&#xff1f; 题目提到“免费”&#xff0c;其实很难有软件可以真正做到。 商业化市场决定了没有一家厂商可以不落俗套。因而我们要探…

[架构之路-177]-《软考-系统分析师》-17-嵌入式系统分析与设计 -2- 系统分析与设计、低功耗设计

目录 1 7 . 4 嵌 入 式 系 统 开 发 17.4.1 开发平台 1 . 交叉开发环境 2 . 交叉编译环境 17. 2 开发流程 1. 过程模型 2 . 分析与设计方法 17.4.3 软硬件协同设计 1 . 软 硬 件 协 同 设 计 方 法 2 . 协 同 设 计 工 具 17.4.4 系统分析与设计 1 . 需求分析 2 .…

CI/CD: GitLab Runner安装注册配置管理

点击上方蓝字⭐️关注“DevOps云学堂”&#xff0c;接收最新技术实践 今天是「DevOps云学堂」与你共同进步的第 21 天 本文是《GitLabCI实践》教程部分内容 GitLab Runner是一个开源项目&#xff0c;用于运行您的作业并将结果发送回GitLab。它与GitLab CI结合使用&#xff0c;G…

计算机网络学习10(ARP协议详解)

ARP 协议&#xff0c;可以说是在协议栈中属于一个偏底层的、非常重要的、又非常简单的通信协议。 开始阅读这篇文章之前&#xff0c;你可以先看看下面几个问题&#xff1a; ARP 协议在协议栈中的位置&#xff1f; ARP 协议在协议栈中的位置非常重要&#xff0c;在理解了它的工…

Linux 内存 pt.1

哈喽大家好&#xff0c;我是咸鱼 今天我们来学习一下 Linux 操作系统核心之一&#xff1a;内存 跟 CPU 一样&#xff0c;内存也是操作系统最核心的功能之一&#xff0c;内存主要用来存储系统和程序的指令、数据、缓存等 关于内存的学习&#xff0c;我会尽量以通俗易懂的方式…

R语言的基本数学运算

目录 一、对象命名原则 二、基本数学运算 2.1 四则运算 2.2 余数和整除 2.3 次方或平方根 2.4 绝对值 2.5 exp()与对数 2.6 科学符号e 2.7 圆周率与三角函数 2.8 四舍五入函数 2.9 近似函数 2.10 阶乘 三、R语言控制运算的优先级 四、无限大 五、非数字&#xf…

OpenCV 实战3 对图像画框、获取图像像素位置

一、函数介绍 opencv中进行鼠标操作主要用到setMouseCallback这个函数&#xff0c;如下&#xff1a; void setMouseCallback(const String& winname, MouseCallback onMouse, void* userdata 0); winname&#xff1a;窗口名称 onMouse&#xff1a;鼠标响应函数&#x…

直击德国PLS展,联诚发倾力打造沉浸式视觉盛宴!

当地时间4月25-28日&#xff0c;备受关注的2023德国法兰克福国际专业灯光音响展ProlightSound&#xff08;以下简称“PLS展”&#xff09;在德国法兰克福盛大召开。联诚发携多款创新产品及多领域的应用解决方案精彩亮相&#xff0c;为全球客户打造沉浸式视觉盛宴&#xff0c;展…

HNU-计算机系统-实验1-PrototypeSystemLab

《计算机系统》 原型机实验报告 班级&#xff1a;计科21XX 学号&#xff1a;20210801XXXX 姓名&#xff1a;wolf 目录 1 实验项目一 1.1项目名称 1.2实验目的 1.3实验资源 2 实验任务 2.1原型机I 2.1.1练习内容 2.1.2思考问题 2.2原型机II-扩充指令集 2.2.1…

《编程思维与实践》1040.字符串消除

《编程思维与实践》1040.字符串消除 题目 思路 每次消除都可能会受到第一次插入字符的影响,所以难以直接判断在哪个位置插入哪个字符后消除的字符数最多. 因此考虑暴力枚举: 在每个位置依此插入A,B,C 对所有情况消除的字符数进行比较,求出最大值. 对于字符串的插入可以利用str…

这个看过吗

el-upload调两个接口&#xff0c;获取二进制文件 &#xff0c;并且上传后不立即执行&#xff0c;通过 this.$refs.upload.submit();触发提交&#xff0c;直接调两个接口&#xff0c;获取到二进制文件后传输 <el-upload:auto-upload"false":data"{report…