框架说明

文件组织

目录结构

JS FA 应用的 JS 模块(entry/src/main/js/module)的典型开发目录结构如下:
图 1 目录结构

An image

目录结构中文件分类如下:

  • .html 结尾的 HTML 模板文件,这个文件用来描述当前页面的文件布局结构。
  • .css 结尾的 CSS 样式文件,这个文件用于描述页面样式。
  • .js 结尾的 JS 文件,这个文件用于处理页面和用户的交互。

各个文件夹的作用:

  • app.js 文件用于全局 JavaScript 逻辑和应用生命周期管理。
  • pages 目录用于存放所有组件页面。
  • common 目录用于存放公共资源文件,比如:媒体资源和 JS 文件。
  • i18n 目录用于配置不同语言场景资源内容,比如应用文本词条,图片路径等资源。

WARNING

i18n 是开发保留文件夹,不可重命名。

文件访问规则

应用资源可通过绝对路径或相对路径的方式进行访问,本开发框架中绝对路径以"/"开头,相对路径以"./"或"../"。具体访问规则如下:

  • 引用代码文件,需使用相对路径,比如:../common/utils.js。
  • 引用资源文件,推荐使用绝对路径。比如:/common/xxx.png。
  • 公共代码文件和资源文件推荐放在 common 下,通过以上两条规则进行访问。
  • CSS 样式文件中通过 url()函数创建<url>数据类型,如:url(/common/xxx.png)。

提示:

当代码文件 A 需要引用代码文件 B 时:

  • 如果代码文件 A 和文件 B 位于同一目录,则代码文件 B 引用资源文件时可使用相对路径,也可使用绝对路径。
  • 如果代码文件 A 和文件 B 位于不同目录,则代码文件 B 引用资源文件时必须使用绝对路径。因为 Webpack 打包时,代码文件 B 的目录会发生变化。

媒体文件格式

表 1 支持的图片格式

格式支持版本支持的文件类型
BMPAPI Version 3+.bmp
JPEGAPI Version 3+.jpg
PNGAPI Version 3+.jpg

存储目录定义

应用使用文件存储接口访问文件时,可以通过使用特定 scheme(只支持 internal)来访问预定义的一些文件存取目录。不同设备上对应的实际位置不同。对于不在下列目录下的文件访问将被拒绝(禁止使用../等方式访问父目录)。

image 组件支持应用私有目录内的图片资源访问。5+

目录类型路径前缀访问可见性说明
应用私有目录internal://app/仅本应用可见随应用卸载删除。

js 标签配置

js 标签中包含了实例名称、页面路由信息。

标签类型默认值必填描述
namestringdefault标识 JS 实例的名字。
pagesArray-路由信息,详见“pages”。

提示:

name、pages 标签配置需在配置文件中的“js”标签中完成设置。

pages

定义每个页面的路由信息,每个页面由页面路径和页面名组成,页面的文件名就是页面名。比如:

{
        ...
        "pages": [
            "pages/index/index",
            "pages/detail/detail"
        ]
        ...
    }

提示:

  • 应用首页固定为"pages/index/index"。
  • 页面文件名不能使用组件名称,比如:text.html、button.html 等。

示例

{
    "app": {
        "bundleName": "com.Xiaomi Watch.player",
        "version": {
            "code": 1,
            "name": "1.0"
        },
        "vendor": "example"
    }
    "module": {
        ...
        "js": [
            {
                "name": "default",
                "pages": [
                "pages/index/index",
                "pages/detail/detail"
                ]
            }
        ],
        "abilities": [
            {
                ...
            }
        ]
    }
}

app.js

每个应用可以在 app.js 自定义应用级生命周期的实现逻辑,包括:

  • onCreate:在应用生成时被调用的生命周期函数。
  • onDestory:在应用销毁时被调用的生命周期函数。

以下示例仅在生命周期函数中打印对应日志:

// app.js
export default {
  onCreate() {
    console.info("Application onCreate");
  },
  onDestroy() {
    console.info("Application onDestroy");
  },
};

多语言支持

基于开发框架的应用会覆盖多个国家和地区,开发框架支持多语言能力后,可以让应用开发者无需开发多个不同语言的版本,就可以同时支持多种语言的切换,为项目维护带来便利。

开发者仅需要通过定义资源文件和引用资源两个步骤,就可以使用开发框架的多语言能力;如果需要在应用中获取当前系统语言,请参考获取语言。

定义资源文件

资源文件用于存放应用在多种语言场景下的资源内容,开发框架使用 JSON 文件保存资源定义。

在文件组织中指定的 i18n 文件夹内放置每个语言地区下的资源定义文件即可,资源文件命名为“语言-地区.json”格式,例如英文(美国)的资源文件命名为 en-US.json。当开发框架无法在应用中找到系统语言的资源文件时,默认使用 en-US.json 中的资源内容。

资源文件内容格式如下:

en-US.json

{
  "strings": {
    "hello": "Hello world!",
    "object": "Object parameter substitution-{name}",
    "array": "Array type parameter substitution-{0}",
    "symbol": "@#$%^&*()_+-={}[]\\|:;\"'<>,./?"
  },

  "files": {
    "image": "image/en_picture.PNG"
  }
}

引用资源

  • 在应用中使用$t方法引用资源,$t 既可以在 html 中使用,也可以在 js 中使用。系统将根据当前语言环境和指定的资源路径(通过$t 的 path 参数设置),显示对应语言的资源文件中的内容。

    表 1 $t 参数说明

参数类型必填描述
pathstring资源路径
paramsArray运行时用来替换占位符的实际内容,占位符分为两种:

具名占位符,例如{name}。实际内容必须用 Object 类型指定,例如:$t('strings.object', { name: 'Hello world' })。

数字占位符,例如{0}。实际内容必须用 Array 类型指定,例如:$t('strings.array', ['Hello world'])。
  • 示例代码
<!-- xxx.html -->
<div>
  <!-- 不使用占位符,text中显示“Hello world!” -->
  <text>{{ $t('strings.hello') }}</text>
  <!-- 具名占位符格式,运行时将占位符{name}替换为“Hello world” -->
  <text>{{ $t('strings.object', { name: 'Hello world' }) }}</text>
  <!-- 数字占位符格式,运行时将占位符{0}替换为“Hello world” -->
  <text>{{ $t('strings.array', ['Hello world']) }}</text>
  <!-- 先在js中获取资源内容,再在text中显示“Hello world” -->
  <text>{{ hello }}</text>
  <!-- 先在js中获取资源内容,并将占位符{name}替换为“Hello world”,再在text中显示“Object parameter substitution-Hello world” -->
  <text>{{ replaceObject }}</text>
  <!-- 先在js中获取资源内容,并将占位符{0}替换为“Hello world”,再在text中显示“Array type parameter substitution-Hello world” -->
  <text>{{ replaceArray }}</text>
  <!-- 获取图片路径 -->
  <image src="{{ $t('files.image') }}" class="image"></image>
  <!-- 先在js中获取图片路径,再在image中显示图片 -->
  <image src="{{ replaceSrc }}" class="image"></image>
</div>
// xxx.js
// 下面为在js文件中的使用方法。
export default {
  data: {
    hello: "",
    replaceObject: "",
    replaceArray: "",
    replaceSrc: "",
  },
  onInit() {
    this.hello = this.$t("strings.hello");
    this.replaceObject = this.$t("strings.object", { name: "Hello world" });
    this.replaceArray = this.$t("strings.array", ["Hello world"]);
    this.replaceSrc = this.$t("files.image");
  },
};

语法

HTML 语法参考

HTML 是一套标记语言,通过组件,事件构建出页面的内容。页面具备数据绑定、事件绑定、列表渲染、条件渲染等高级能力。

页面结构

<!-- xxx.html -->
<div class="item-container">
  <text class="item-title">Image Show</text>
  <div class="item-content">
    <image src="/common/xxx.png" class="image"></image>
  </div>
</div>

数据绑定

<!-- xxx.html -->
<div onclick="changeText">
  <text> {{content[1]}} </text>
</div>
// xxx.js
export default {
  data: {
    content: ["Hello World!", "Welcome to my world!"],
  },
  changeText: function () {
    this.content.splice(1, 1, this.content[0]);
  },
};

提示:

  • 针对数组内的数据修改,请使用 splice 方法生效数据绑定变更。
  • html 中的 js 表达式不支持 ES6 语法。

CSS 语法参考

CSS 是描述 HTML 页面结构的样式语言。所有组件均存在系统默认样式,也可在页面 CSS 样式文件中对组件、页面自定义不同的样式。

样式导入

为了模块化管理和代码复用,CSS 样式文件支持 @import 语句,导入 CSS 文件。

声明样式

每个页面目录下存在一个与布局 html 文件同名的 css 文件,用来描述该 html 页面中组件的样式,决定组件应该如何显示。

  1. 内部样式,支持使用 style、class 属性来控制组件的样式。例如:
<!-- index.html -->
<div class="container">
  <text style="color: red">Hello World</text>
</div>
/* index.css */
.container {
  justify-content: center;
}
  1. 文件导入,合并外部样式文件。例如,在 common 目录中定义样式文件 style.css,并在 index.css 文件首行中进行导入:
/* style.css */
.title {
  font-size: 50px;
}
/* index.css */
@import "../../common/style.css";
.container {
  justify-content: center;
}

选择器

css 选择器用于选择需要添加样式的元素,支持的选择器如下表所示:

选择器样例样例描述
.class.container用于选择 class="container"的组件。
#id#titleId用于选择 id="titleId"的组件。
,.title, .content用于选择 class="title"和 class="content"的组件。

示例:

<!-- 页面布局xxx.html -->
<div id="containerId" class="container">
  <text id="titleId" class="title">标题</text>
  <div class="content">
    <text id="contentId">内容</text>
  </div>
</div>
/* 页面样式xxx.css */
/* 对class="title"的组件设置样式 */
.title {
  font-size: 30px;
}

/* 对id="contentId"的组件设置样式 */
#contentId {
  font-size: 20px;
}

/* 对所有class="title"以及class="content"的组件都设置padding为5px */
.title,
.content {
  padding: 5px;
}

伪类

css 伪类是选择器中的关键字,用于指定要选择元素的特殊状态。

名称支持组件描述
:activeinput[type="button"]表示被用户激活的元素,如:被用户按下的按钮。轻量级智能穿戴上伪类选择器上仅支持 background-color 和 background-image 的样式设置。
:checkedinput[type="checkbox"、type="radio"]表示 checked 属性为 true 的元素。轻量级智能穿戴上伪类选择器上仅支持 background-color 和 background-image 的样式设置。

伪类示例如下,设置按钮的:active 伪类可以控制被用户按下时的样式:

<!-- index.html -->
<div class="container">
    <input type="button"class="button"value="Button"></input>
</div>
/* index.css */
.button:active {
  background-color: #888888; /*按钮被激活时,背景颜色变为#888888 */
}

样式预编译

预编译提供了利用特有语法生成 css 的程序,可以提供变量、运算等功能,令开发者更便捷地定义组件样式,目前支持 less、sass 和 scss 的预编译。使用样式预编译时,需要将原 css 文件后缀改为 less、sass 或 scss,如 index.css 改为 index.less、index.sass 或 index.scss。

  • 当前文件使用样式预编译,例如将原 index.css 改为 index.less:
/* index.less */
/* 定义变量 */
@colorBackground: #000000;
.container {
  background-color: @colorBackground; /* 使用当前less文件中定义的变量 */
}
  • 引用预编译文件,例如 common 中存在 style.scss 文件,将原 index.css 改为 index.scss,并引入 style.scss:
/* style.scss */
/* 定义变量 */
$colorBackground: #000000;
在 index.scss 中引用:

/* index.scss */
/* 引入外部scss文件 */
@import'../../common/style.scss';
.container{
    background-color: $colorBackground; /* 使用style.scss中定义的变量 */
}

提示:

引用的预编译文件建议放在 common 目录进行管理。

JS 语法参考

JS 文件用来定义 HTML 页面的业务逻辑,支持 ECMA 规范的 JavaScript 语言。基于 JavaScript 语言的动态化能力,可以使应用更加富有表现力,具备更加灵活的设计。下面讲述 JS 文件的编译和运行的支持情况。

语法

支持 ES6 语法。轻量级智能穿戴支持的 ES6 语法有限,仅支持以下 ES6 语法:

  1. let/const
  2. arrow functions
  3. class
  4. default value
  5. destructuring assignment
  6. destructuring binding pattern
  7. enhanced object initializer
  8. for-of
  9. rest parameter
  10. template strings
  • 模块声明

    使用 import 方法引入功能模块:

import router from "@system.router";
  • 代码引用

    使用 import 方法导入 js 代码:

import utils from "../../common/utils.js";

对象

  • 页面对象

    属性类型描述
    dataObject/Function页面的数据模型,类型是对象或者函数,如果类型是函数,返回值必须是对象。属性名不能以$或_开头,不要使用保留字 for, if, show, tid。
    $refsObject持有注册过 ref 属性的 DOM 元素或子组件实例的对象。

获取 DOM 元素

  1. 通过$refs 获取 DOM 元素
<!-- index.html -->
<div class="container">
  <image-animator
    class="image-player"
    ref="animator"
    images="{{images}}"
    duration="1s"
    onclick="handleClick"
  ></image-animator>
</div>
 // index.js
    export default {
    data: {
        images: [
        { src: '/common/frame1.png' },
        { src: '/common/frame2.png' },
        { src: '/common/frame3.png' },
        ],
    },
    handleClick() {
        const animator = this.$refs.animator; // 获取ref属性为animator的DOM元素
        const state = animator.getState();
        if (state === 'paused') {
                animator.resume();
            } elseif (state === 'stopped') {
                animator.start();
            } else {
                animator.pause();
            }
        },
    };

生命周期接口

  • 页面生命周期
属性类型参数返回值描述触发时机
onInitFunction页面初始化页面数据初始化完成时触发,只触发一次。
onReadyFunction页面创建完成页面创建完成时触发,只触发一次。
onShowFunction页面显示页面显示时触发。
onHideFunction页面消失页面消失时触发。
onDestroyFunction页面销毁页面销毁时触发。
onBackPressFunction-当用户点击返回实体按键时触发该事件。如果事件响应方法最后返回true表示不返回,自己处理业务逻辑(完毕后开发者自行调用 API 返回);否则:不返回数据,或者返回其它数据,表示遵循系统逻辑:返回到上一页。

页面 A 的生命周期接口的调用顺序:

  • 打开页面 A:onInit() -> onReady() -> onShow()

  • 在页面 A 打开页面 B:onHide() -> onDestroy()

  • 从页面 B 返回页面 A:onInit() -> onReady() -> onShow()

  • 退出页面 A:onHide() -> onDestroy()

  • 页面隐藏到后台运行:onHide()

  • 页面从后台运行恢复到前台:onShow()

  • 应用生命周期

属性类型参数返回值描述触发时机
onCreateFunction应用创建当应用创建时调用。
onDestroyFunction应用退出当应用退出时触发。
Last Updated:
Contributors: 550, lvzongchao, wangze