引言
一、本文的目的
1.本文是读书笔记,学习笔记。包含书中内容的对比总结、关键提炼、知识补充、思维导图。在JS UI开发的学习过程,会着重思考与Java UI开发的差异。
2.鉴于官方文档关于JS UI的讲解很散乱、不聚焦,在北向HCIA学习路上就需要各位大佬出的书和视频来助力,近期会从三本书籍去学习JS UI开发去学习和祖做笔记,并对三本书关于这一块儿知识的讲解做一个总结,最后解析JS UI官方示例工程。书籍分别是《鸿蒙应用程序开发-董昱》、《鸿蒙操作系统应用开发实践-中科院》、《鸿蒙操作系统开发入门经典-徐文礼》
二、学习《鸿蒙应用程序开发-董昱》的体验
1.代码很规范!很规范!很规范!有注解
2.董昱老师的示例代码目前已学习到的,没有是直接从官方文档的示例代码拿下来的,很用心了。示例代码块的上方都有所在文件的位置!!!!不需要焦虑代码该敲在哪儿的问题了。
3.在JS UI这块儿官方文档的知识很散乱,不聚焦,董昱老师的讲解很系统
4.董昱老师对参数的解释很到位
5.方法的图解、概念的图示都很到位
6.最后也是最关键的一点!董昱老师的《鸿蒙应用程序开发》有免费的配套课程!!!!鸿蒙应用程序开发视频教程
7.学习JS开发官方文档,以下两个文档比较好。
一、JavaScript UI设计
5.0概述
Java UI与JS UI
区别
- Java UI开发 安卓型(事件式编程范式)
- JS UI开发 Web前端(声明式编程范式)
联系
- JS UI更加倾向于界面开发,在复杂业务逻辑方面,需要Java来帮忙。
- 在轻量级智能穿戴设备上的JS UI会更轻量级一点,并不能使用所有的JS UI特性
HML与HTML
区别
- HML:鸿蒙标记语言,表述用户界面结构
- HTML:超文本标记语言,描述 web文档的一种标记语言(大家熟知不做赘述)
联系
- 一门标记语言
- 一种文件类型
- HTML与HML的用法及其相似
5.1 初识Js UI
5.1.1 JS实例与页面
(1)概念辨析
1.创建工程
继承的类有变化
- 之前:Ability
- 现在:AceAbility
主要管理JS目录下的文件
关于:common.images文件夹的疑惑,其实就是形式上变了一点点而已,不影响的。
2.实例与页面
实例(JavaScript实例):
- 一组与功能相关的用户界面和功能
- 默认的实例名称为default
实例与Ability
- 每个独立的实例都被独立的Ability管理
- default实例默认被MainAbility管理
实例与Page
- 在实例中,可以创建多个用户界面,其中每个用户界面被称为一个页面(Page)
实例、页面、Ability可视化关系图
JS UI的页面(Page)与Java UI中的界面(AbilitySlice)
- 两者相似
- 要用于承载单个页面的具体逻辑实现和界面UI,是应用显示、运行和跳转的最小单元
实例配置
位置:config.json
属性:
- name:实例名,默认default
- pages:声明实例所包含的页面
- Page属性是页面路径组成的数组
- 页面路径是以实例目录为根目录的路径,不带后缀
window:声明与虚拟像素相关的选项
- designWidth:虚拟宽度(px像素此时也是虚拟)
- autoDesignWidth:是否启动(fasle且不设虚拟宽度则px为实际物理宽度)
代码:
(2)概念补充
关于视觉中的基础概念补充HarmonyOS官方文档-设计-视觉风格-基础概念
虚拟像素单位:vp
- 虚拟像素(virtual pixel)是一台设备针对应用而言所具有的虚拟尺寸(区别于屏幕硬件本身的像素单位)。它提供了一种灵活的方式来适应不同屏幕密度的显示效果。
字体像素单位:fp
- 字体像素(font pixel) 大小默认情况下与 vp 相同,即默认情况下 1 fp = 1vp。如果用户在设置中选择了更大的字体,字体的实际显示大小就会在 vp 的基础上乘以 scale 系数,即 1 fp = 1 vp * scale。
关于尺寸单位的补充HarmonyOS官方文档-Native API-JS API-语法-CSS语法参考
逻辑像素px(文档中以
1. 默认卡片具有的逻辑宽度为150px,实际显示时会将页面布局缩放至屏幕实际宽度,如100px在宽度为300的卡片上,实际渲染为200物理像素(从150px向300物理像素,所有尺寸放大2倍)。
2. 额外配置autoDesignWidth为true时,逻辑像素px将按照屏幕密度进行缩放,如100px在屏幕密度为3的设备上,实际渲染为300物理像素。应用需要适配多种设备时,建议采用此方法。
5.1.2 新JS实例
两种方法
创建新的JS UI的PA,并同时创建实例
解疑:Launcher Ability
仅创建一个新的实例
Ability与实例的指定
跟Java中Ability与AbilitySlice的指定是类似的
- Java中通过setUIContent()
- Js中通过setInstanceName()
注:
1.默认情况MainAbility加载default实例,不需要通过setInstanceName()传入default这个实例名称字符串。
2.setInstanceName(String name)的参数“name”指实例名称,实例名称与config.json文件中module.js.name的值对应。
5.1.3 初识页面
讲JS开发目录的介绍,着重讲清楚了i18n目录的来历、结构、用处。
其他内容见HarmonyOS官方文档-开发-UI-JS UI框架-初步体验JS FA应用-JS FA概述
5.1.4页面跳转
(1)概念
页面栈:JS UI中,支持页面的层级结构,即上层页面遮盖下层页面,形成栈结构。
页面路由:页面的跳转关系被称为页面路由,由JS UI的router模块来管理,需要js文件的export default的代码块前进行导入
- import router from '@system.router';
(2)router模块
ctrl+鼠标左键router进去以后,对英文注解进行翻译
方便记忆的方法总结(老师书上还对参数做了一定的解释,特别棒)
- push(obj: Router Options):跳转(覆盖)
- replace(obj: RouterOptions):跳转(销毁)
- back(obj?: BackRouterOptions):返回
- clear():清除(被遮盖的页面)
- getLength():堆栈中的页数
- getState():获取有关当前页面状态的信息,返回IRouterState对象,该对象包括index、name、path。
- index:整型,表示当前页面所在的页面栈中的位置,从底层到顶层是从1开始计数的
- name:字符串,表示当前页面的文件名
- path:字符串,表示当前页面的路径
- /**
- * @Syscap SysCap.ACE.UIEngine
- */
- export default class Router {
- /**
- * Navigates to a specified page in the application based on the page URL and parameters.
- * 根据页面URL和参数导航到应用程序中的指定页面。
- * @param obj
- */
- static push(obj: RouterOptions): void;
- /**
- * Replaces the current page with another one in the application. The current page is destroyed after replacement.
- * 用应用程序中的另一页替换当前页。替换后,当前页面将被销毁。
- * @param obj
- */
- static replace(obj: RouterOptions): void;
- /**
- * Returns to the previous page or a specified page.
- * 返回上一页或指定页。
- * @param obj
- */
- static back(obj?: BackRouterOptions): void;
- /**
- * Clears all historical pages and retains only the current page at the top of the stack.
- * 清除所有历史页面,并在堆栈顶部仅保留当前页面。
- */
- static clear(): void;
- /**
- * Obtains the number of pages in the current stack.
- * 获取当前堆栈中的页数。
- * @returns Number of pages in the stack. The maximum value is 32.
- */
- static getLength(): string;
- /**
- * Obtains information about the current page state.
- * 获取有关当前页面状态的信息。
- * @returns Page state.
- */
- static getState(): RouterState;
- }
出入栈与方法的对应
- push:新页面入栈
- back:当前页面出栈
- replace:把当前页面出栈、替换的新页面入栈
- clear:把当前页面以下的所有页面都出栈
(3)实现index页面跳转到secpage页面
index.js中实现跳转代码
- //index.js
- //导入router模块
- import router from '@system.router';
- export default {
- data: {
- harmony:null
- },
- onInit() {
- this.harmony ="董昱老师YYDS"
- },
- //跳转到secpage的方法
- toSecPage(){
- //通过push方法入栈
- router.push({
- //指定跳转位置
- uri:'pages/index/secpages/secpages',
- //传递数据
- params:{
- harmony: this.harmony
- }
- });
- }
- }
进行一些基本的设置以后,动图奉上!
(4)使用被传递的数据,并实现从SecPage返回index
在secpage.js里接收index传过来数据,并通过console.info(message)方法将字符串变量以HiLog的形式输出
- //secpage.js
- import router from '@system.router';
- export default {
- data: {
- title: '跳转成功'
- },
- onInit(){
- //输出刚被传递出来的Harmony字符串
- console.info(this.harmony);
- },
- back(){
- router.back();
- }
- }
5.1.5 页面的生命周期函数
这一块儿,书中没有官方文档讲得详细,图解也没有那么易懂,所以采取的互相补充的方式
HarmonyOS官方文档-JS API参考-手机、平板、智能屏和智能穿戴开发-框架说明-生命周期
(1)页面生命周期(总结+补充)
页面生命周期(书中只讲了前5个即从初始化到销毁的生命周期)
(2)页面A的生命周期接口的调用顺序
- 打开页面A:onInit() -> onReady() -> onShow()
- 在页面A打开页面B:onHide()
- 从页面B返回页面A:onShow()
- 退出页面A:onBackPress() -> onHide() -> onDestroy()
- 页面隐藏到后台运行:onInactive() -> onHide()
- 页面从后台运行恢复到前台:onShow() -> onActive()
注意:
- 调用生命周期函数,可以通过conslole.info()进行打印
- 通过onBackPress()方法监听系统返回事件
- 一个完整的页面生命周期中,至少会被调用一次,并且onInit() 、onReady()、onDestroy()仅能被调用一次
(3)Java UI中与JS UI中Page Ability的对比(补充)
相关官方文档
JS UI
Java UI
Page的组成单元
- Java UI中是AbilitySlice(AbilitySlice主要用于承载单个页面的具体逻辑实现和界面UI,是应用显示、运行和跳转的最小单元)
- JS UI中是JavaScript实例(见5.1.1)
组成单元的生命周期与Page Ability的生命周期
组成单元的生命周期依托于Page的生命周期。组成单元的生命周期与Page的相应回调类似,但组成单元还具有独立于Page的生命周期变化,如同一Page中的AbilitySlice之间导航时,此时Page的生命周期状态不会改变。
图解
Java UI
Js UI
5.1.6 应用对象(应用生命周期)
(1)应用生命周期(4个)
注意
- 在任何一个页面中,通过this.$app代码即可获取当前的应用对象,应用对象应用自身的生命周期,开发者可以在应用对象中实现JavaScript全局变量。
- 在onCreate()、onDestroy()两种方法中可以实现数据库的管理,例如:在前者方法中执行一些初始化操作(网络连接、账号检查)、在后者方法中检查数据库是否关闭,如果未关闭则要立即关闭。
(2)共享应用对象的变量(全局变量)
应用对象是一个单例,在应用对象中定义的变量可以在所有页面中进行调用。
在app.js中添加1个变量jumpCount,用于记录用户的页面跳转次数,然后创建该变量的Get/Set方法
- //app.js
- export default {
- data:{
- jumpCount:null
- },
- //获取页面跳转次数
- getJumpCount(){
- return this.jumpCount;
- },
- //设置页面的跳转次数
- setJumcount(){
- this.jumpCount =count;
- },
- //页面的跳转次数 +1
- increaseJumpCount(){
- this.jumpCount ++;
- },
- onCreate() {
- this.jumpCount =0; //初始化页面的跳转次数为0
- console.info('AceApplication onCreate');
- },
- onDestroy() {
- console.info('AceApplication onDestroy');
- }
- };
对index.js和secpage.js进行相应的设置最后的日志