昨天我们已经跟着坚果构建了首个蓝河应用,接下来我们就开始后面的内容。

蓝河应用程序包基础知识【坚果派-坚果】

作者:坚果

华为HDE,润开鸿生态技术专家,坚果派创始人,OpenHarmony布道师,开发者联盟优秀讲师,2023年开源之夏导师,2023年OpenHarmony应用创新赛导师,OpenHarmony金融应用创新赛导师,RISC-V+OpenHarmony应用创意赛导师,OpenHarmony三方库贡献者,开放原子开源基金会技术+生态贡献者,第一批开放原子开源讲师,曾受邀参加2022,2023HDC大会,OpenHarmony校源行开源大使,InfoQ签约作者,CSDN博客专家,电子发烧友MVP,51CTO博客专家博主,阿里云博客专家,专注于分享的技术包括HarmonyOS/OpenHarmony,ArkUI-X,元服务,服务卡片,华为自研语言,在2022年战码活动中,带领100余人完成pr的提交,配合孵化三个小队长。也在此活动中累计完成1.5W行代码提交,在2023年OpenHarmony创新赛中。累计辅导60+队伍,完成作品的提交,并有9个获奖。在2023年OpenHarmony金融应用创新赛中。累计辅导14+队伍,完成作品的提交。

本文对项目的文件目录及相关内容进行了介绍,包括蓝河应用文件结构讲解,配置信息、新增页面等。

一、蓝河应用项目目录介绍

通过 BlueOS Studio 新建一个项目,这个项目已经包含了项目配置示例页面的初始代码,项目根目录主要结构如下:

├── scripts                   工具脚本文件
├── src
│   ├── assets                # 公用资源
│   │   ├── images            图片资源
│   │   └── styles            应用样式
│   ├── pages                 页面目录
│   │   ├── Demo              应用首页
│   │   └── DemoDetail        应用详情页
│   ├── app.ux                app.ux文件。
│   └── manifest.json         项目配置文件,配置应用图标、页面路由等
└── jsconfig.json             js 配置文件,用于语法校验
└── package.json              定义项目需要的各种模块及配置信息

截图如下:image-20231229234059318

1.1目录的简要说明如下:

  • src:项目源文件夹
  • app.ux 文件用于全局 JavaScript 逻辑和应用生命周期管理。
<script>
/**
 * 应用级别的配置,供所有页面公用
 */

export default {
  onCreate() {},
  
  onDestroy(){}
}
</script>

二、配置信息

每个应用都要有专属的名称,图标等,这些信息都需要在manifest.json文件中配置。详见文档manifest 文件

2.1应用包名(package)

应用包名,是区别于其他应用的唯一标识

推荐采用 com.company.module 的格式,示例如下:

{
  "package": "com.jianguo.demo",
}

2.2应用名称(name)

应用名称,6 个汉字以内,与应用商店保存的名称一致;框架提供保存到桌面的功能,桌面上显示的应用名即为此属性

示例如下:

{
   "name": "坚果手表",
}

2.3应用图标(icon)

规则为正方形(不能是圆角),且务必无白边

{
  "icon": "/assets/images/logo.png"
}

2.4应用版本名称、版本号(versionName、versionCode)

应用版本名称、版本号为开发者的应用包维护的版本信息

应用版本名称为主版本.次版本格式

应用版本号为整数,从1开始,每次更新上架请自增 1

示例如下:

{
  "versionName": "1.0.0",
  "versionCode": 1,
}

2.5配置接口列表(features)

在使用接口时,需要先在 manifest 中声明接口。在每个接口文档的顶部,都附有声明接口的配置代码

以 fetch 网络请求和路由router为例,示例如下:

  "features": [
    {
      "name": "blueos.app.appmanager.router"
      
    },
    { "name": "blueos.communication.network.fetch" }
  ],

2.6deviceTypeList(设备类型)

可选值有:watch, watch-square, watch-round, tv , car, phone

  "deviceTypeList": [
    "watch",
    "watch-square"
  ],

三、新增页面

新增及配置页面,需要依赖manifest.jsonrouter配置

3.1router

router,路由,用于定义页面的实际地址、跳转地址。如果 ux 页面没有配置路由,则不参与项目编译。一个目录下最多只能存在一个主页面文件(不包括组件文件)

首页 (router.entry)

首页,即应用平台启动时默认打开的页面。首页需配置为应用中某页面的名称,即在<ProjectName>/src目录下,页面目录的相对路径

假设工程根目录如下所示

└── src
    └── Demo                  页面目录,存放各自页面私有的资源文件和组件文件
        └── index.ux          页面文件,文件名不必与父文件夹相同(推荐index.ux)

假设首页为 Demo 目录下的 index.ux 文件,则首页对应的页面名称为Demo

{
  "router": {
    "entry": "Demo"
  }
}
页面路由对象(router.pages)

页面路由对象,key 为页面名称(<ProjectName>/src目录下,页面目录的相对路径),value 为页面具体路由配置,key 不要重复

页面具体路由配置(router.pages 的 value)包括以下属性:

  • component:页面对应的 ux 文件名
  • path:页面路径,不填则默认为页面名称(<ProjectName>/src目录下,页面目录的相对路径

示例如下:

假设工程根目录如下所示

└── src
 └── pages
    |── Demo                  页面目录,存放各自页面私有的资源文件和组件文件
    |   └── index.ux          页面文件,文件名不必与父文件夹相同(推荐index.ux)
    └─── DemoDetail           页面目录,存放各自页面私有的资源文件和组件文件
            └── index.ux      页面文件,文件名不必与父文件夹相同(推荐index.ux)

当页面名称(router.pages 的 key)为Demo时,对应的页面配置(router.pages 的 value)包括:

  • component:页面对应的 ux 文件名index
  • path:页面路径,默认为页面名称Demo
  "router": {
    "entry": "pages/Demo",
    "pages": {
      "pages/Demo": {
        "component": "index"
      },
      "pages/DemoDetail": {
        "component": "index"
      }
    }
  },

现在,开发者就可以通过/Demo访问到 Demo 目录下的 index.ux 页面了

四、UX 文件

APP、页面和自定义组件均通过 ux 后缀文件编写,ux 后缀文件由 template 模板、style 样式javascript 代码 3 个部分组成,一个典型的页面 ux 后缀文件示例如下:

<template>
  <!-- template里只能有一个根节点 -->
  <div class="demo-page">
    <text class="title">欢迎打开{{title}}</text>
    <!-- 点击跳转详情页 -->
    <input class="btn" type="button" value="跳转到详情页" onclick="routeDetail" />
  </div>
</template>

<style>
  .demo-page {
    flex-direction: column;
    justify-content: center;
    align-items: center;
  }

  .title {
    font-size: 40px;
    text-align: center;
  }

  .btn {
    width: 550px;
    height: 86px;
    margin-top: 75px;
    border-radius: 43px;
    background-color: #09ba07;
    font-size: 30px;
    color: #ffffff;
  }
</style>

<script>
  import router from '@blueos.app.router'

  export default {
    // 页面级组件的数据模型,影响传入数据的覆盖机制:private内定义的属性不允许被覆盖
    data: {
      title: '示例页面',
    },
    routeDetail() {
      // 跳转到应用内的某个页面,router用法详见:文档->接口->页面路由
      router.push({
        uri: '/DemoDetail',
      })
    },
  }
</script>

4.1style 样式

用于描述 template 模板的组件样式,决定组件应该如何显示

样式布局采用 CSS Flexbox(弹性盒)样式,针对部分原生组件,对 CSS 进行了少量的扩充以及修改

为了解决屏幕适配问题,所有与大小相关的样式(例如 width、font-size)均以基准宽度(默认 750px)为基础,根据实际屏幕宽度进行缩放

文件导入

支持 2 种导入外部文件的方式

<!-- 导入外部文件, 代替style内部样式 -->
<style src="./style.css"></style>

<!-- 合并外部文件 -->
<style>
  @import './style.css';
  .a {
  }
</style>
模板内部样式

支持使用 style、class 属性来控制组件的样式

<!-- 内联inline -->
<div style="color: #f00; margin: 10px;" />
<!-- class声明 -->
<div class="normal append" />

4.2javascript 代码

用来定义页面数据和实现生命周期接口

语法

支持 ES6 语法

模块声明

蓝河应用中支持ES6module标准,使用import引入 js 依赖,同时支持 CommonJs 规范,使用require引入 js 依赖(具体参看功能接口部分文档说明)

// 首先在 `manifest.json` 中配置 `fetch` 接口

// require引入
const fetch = require('@blueos.communication.network.fetch')

// import引入
import fetch from '@blueos.communication.network.fetch'
代码引用

JS 代码引用推荐使用 import 来导入, 例如:

import utils from '../Common/utils.js'

注意: 蓝河应用环境不是 node 环境,不要引用 node 原生模块,如 import fs from 'fs'

app.ux

当前app.ux编译后会包含manifest配置信息,所以请不要删除/**manifest**/的注释内容标识。

您可以在<script>中引入一些公共的脚本,并暴露在当前 app 的对象上,如下所示,然后就可以在页面 ux 文件的 ViewModel 中,通过this.$app.$def.util访问。

<script>
  /**
   * 应用级别的配置,供所有页面公用
   */
  import util from './util'

  export default {
    showMenu: util.showMenu,
    createShortcut: util.createShortcut,
    util,
  }
</script>

五、参考文档

教程

UI组件

JS API

工具

FAQ

蓝河操作系统

vivo 重磅官宣自研“蓝河操作系统”:永不兼容安卓应用,由 Rust 编写框架,还引入 AI 大模型!


坚果
74 声望7 粉丝

坚果派联合创始人、华为HDE,OpenHarmony MVP