鸿蒙JS开发项目总结

第一部分 鸿蒙JS基础入门

Project Type:

  • Service 没有界面, 只提供数据服务
  • Application 有界面, 提供数据服务
  1. 鸿蒙不能打印对象, 只能打印字符串
console.log('888:' +JSON.stringify(data))//对象转字符串打印

const target = JSON.parse(res.data)//把JSON规则的字符串转换为JSONObject
  1. 预览器会默认被当做PC环境, 无法请求数据, 建议用真机/模拟器来调试网络请求

  2. build生成的不是apk, 而是.hap

  3. 想要实现可视化编程: /js/default/pages 右键-->New-->JS Visual

1.不同设备

在.css中:

//不同设备之间的样式设置
@media screen and (device-type: wearable){
  .title{
    font-size: 20px;
    color: #ffffff;
  }
}

@media screen and (device-type: phone) and (orientation: landscape){
  .title{
    font-size: 60px;
  }
}

2.导入资源使用

/// 在路径 common/datas/ 下  新建frames.js:
export default[
  {
    //⚠️通过js去引进图标文件的时候, 一定要使用绝对路径
    src: "/common/images/other/0.jpg",
  },
  {
    src: "/common/images/other/1.jpg",
  },
  ...
]

/// 在其他js文件中, 使用frames.js的资源;
import frames from "../../common/datas/frames.js"
//⚠️在js中导入第三方数据的时候, 一定要使用相对路径
export default{
  data:{
    frames,
  },
  handleStart(){
    this.$refs.animator.start();
  },
  ...
},

3.TodoList应用构建

页面样式设计注意事项

  1. 页面css支持id、class、tag选择器, 建议使用class选择器
  2. 页面样式基于flex弹性布局进行设置, 默认是flex弹性布局, 需要注意, 弹性布局会自动的拉升和压缩内部元素模块宽度、高度
  3. 鸿蒙封装的js组件, 有个专门的样式说明, 与传统CSS写法有很大差异

示例:

在js/defalut/common/datas/todoList.js中:

//第三方 JSON 数据导入,注意使用相对路径
export default [
    {
        info: '给老王打个电话',
        status: true
    },
    {
        info: '输出工作计划',
        status: false
    },
    {
        info: '和小王对接需求',
        status: true
    },
    {
        info: '整理客户资料',
        status: false
    },
    {
        info: '和朋友一起聚餐',
        status: false
    }
]

在index.html中:

<div class="container">
    <text class="title">待办事项</text>
    <div class="item" for="{{todoList}}">
        <text class="todo">{{$item.info}}</text>
        <switch showtext="true" checked="{{ $item.status }}"
                texton="完成" textoff="待办"
                class="switch"></switch>
        <button class="remove" onclick="remove($idx)">删除</button>
    </div>
    <div class="info">
        <text class="info-text">您还有</text>
        <text class="info-num">{{todoCount()}}</text>
        <text class="info-text">件事情待办,加油!</text>
    </div>
    <div class="add-todo">
        <input class="plan-input" type="text"></input>
        <button class="plan-btn" onclick="addTodo">添加待办</button>
    </div>
</div>

在index.js中:


import todoList from "../../common/datas/todoList.js"
export default {
    data: {
        todoList
    },
    //普通事件
    remove(index){
        console.log(index)
        this.todoList.splice(index, 1)
    },
    switchChange(index){
        this.todoList[index].status = !this.todoList[index].status
    },
    addTodo(){
        this.todoList.push({
            info:'IDE工具无法监听键盘输入',
            status: false
        })
    },

    //定义计算属性
    computed:{
        todoCount(){
            let num = 0;
            this.todoList.forEach(element=>{
                if(!element.status){
                    num++
                }
            })
            return num
        }
    }
}

4.多端设备规则

在手机P40设备上1px = 3物理像素

在TV设备上1px = 2 物理像素

在穿戴wearable设备上 1px = 2 物理像素

// 我们常用类型来进行判断,按照 phone、tv、wearable 顺序输出不同响应式的页面布局
@media screen and (device-type: phone)  {}
@media screen and (device-type: tv)  {}
@media screen and (device-type: wearable)  {}

5.路由传参

// 页面跳转并传参
switch(index){
  case 0:
    router.push({
      uri:"pages/index/index",
      params:{
        info:"这是路由传递的参数"
      }
    });
    break;
  case 1:
    ...
}
    
    
// 接收页面跳转后传递过来的参数, 在index.html中直接使用:
<text>{{info}}</text>

6.项目配置

{
  "app": {
    "bundleName": "net.newsmth.newsmthcard", //包名
    "vendor": "newsmth",
    "version": {
      "code": 1000000,
      "name": "1.0.0"
    }
  },
  "deviceConfig": {},
  "module": {
    "package": "net.newsmth.newsmthcard",
    "name": ".MyApplication",
    "mainAbility": "net.newsmth.newsmthcard.MainAbility",
    "deviceType": [
      "phone"
    ],
    "distro": {
      "deliveryWithInstall": true,
      "moduleName": "entry",
      "moduleType": "entry",
      "installationFree": false
    },
    "abilities": [
      {
        "skills": [
          {
            "entities": [
              "entity.system.home"
            ],
            "actions": [
              "action.system.home"
            ]
          }
        ],
        "orientation": "portrait",//固定手机竖向展示
        "visible": true,
        "name": "net.newsmth.newsmthcard.MainAbility",
        "icon": "$media:icon",
        "description": "$string:mainability_description",
        "label": "$string:entry_MainAbility",
        "type": "page",
        "launchType": "standard"
      },
      {
        "name": "net.newsmth.newsmthcard.DetailAbility",
        "icon": "$media:icon",
        "description": "$string:detailability_description",
        "label": "$string:entry_DetailAbility",
        "type": "page",
        "launchType": "standard"
      }
    ],
    "js": [
      {
        "pages": [
          "pages/index/index",
          "pages/detail/index"
        ],
        "name": "default",
        "window": {
          "designWidth": 720,
          "autoDesignWidth": true
        }
      }
    ]
  }
}

很多功能JS实现不了, 比如数据库, 需要使用java

7.卡片布局判断

<div class="grid_pattern_layout">
<!--    1*2-->
    <div if="{{ mini }}" class="mini_container">
        <image src="/common/image_1.png" class="mini_image"></image>
        <text class="mini_text">标题mini</text>
    </div>

<!--    2*2-->
    <div class="normal_container">
         <!--    2*4--> 
        <div if="{{ dim2X4 }}" class="preview_container">
        </div> 
      
        <!--    4*4-->
        <div class="detail_container">
        </div>
      
    </div>
</div>

8.toast

import prompt from '@system.prompt';

export default {
  
  test1(e) {
            //触发弹窗
        prompt.showToast({
            message: '弹窗内容'
        })
    },
}

第二部分 服务卡片

1.service Widget(服务卡片)

  • 显示卡片的方法:

    1.按住App的图标, 向上滑动, 当手指划出图标后会弹出卡片. 例如, 运动健康, 12的卡片和22的卡片 2*4

    • 2.直接将卡片放到桌面上:

      (1)使用1的方式弹出卡片, 然后点击右上角的图钉

      (2)按住App的图标, 然后点击"服务卡片",然后选择相应的卡片, 点击"添加到桌面"

      (3)长按桌面已有卡片, 然后点击"更多服务卡片"进行选择

  • 服务卡片的事件 -—- 与宿主程序进行交互的四个方法(在java/MainAbility.java中)

    1. onCreateForm(Intent intent) 卡片创建时触发
    2. onUpdateForm(long formld) 卡片更新时触发, formld:卡片对应的id
    3. onDeleteDorm(long formld) 卡片删除时触发
    4. onTriggerFormEvent(long formld, String message) 卡片与宿主程序交互时触发

如何同时控制多个服务卡片

// 在java/MainAbility.java中:
@Override
protected ProviderFormInfo onCreateForm(Intent intent) {
    HiLog.info(TAG, "onCreateForm");
    long formId = intent.getLongParam(AbilitySlice.PARAM_FORM_IDENTITY_KEY, INVALID_FORM_ID);
   // 将每一个创建的服务卡片的formid保存到list中
}
@Override
protected void onDeleteForm(long formId) {
    //删除不需要的服务卡片
}

2.行内样式

标签显示模式转换 display块转行内:display:inline;

行内转块:display:block;

块、行内元素转换为行内块: display: inline-block;

比如实现like评论结尾的"删除"按钮:
<text class="content">
    <span>{{info.name}}:{{info.content}}</span>
    <span if="{{info.canDelete}}" class="delete" @click="delete">删除</span>
</text>

3.鸿蒙UI框架生命周期

JS UI的Ability生命周期
下面是几个主要生命周期函数。
● onCreate ()
当应用创建时调用。(应用的生命周期)
● onInit ()
页面数据初始化完成时触发,只触发一次。
● onReady ()
页面创建完成时触发,只触发一次。
● onShow ()
页面显示时触发。
● onHide ()
页面消失时触发。
● onDestroy ()
页面销毁时触发

4.鸿蒙js开发暗黑模式适配

@media screen and (dark-mode: true){
    .title{
        color: aliceblue;
    }
}

方案二: 关闭暗黑模式追随系统

config.json里module层级下有个colorMode,可以根据需要设置light/dark/auto

5.js 中编码(encode)和解码(decode)的三种方法

unescape, decodeURI, decodeURIComponent✅

6.js map的key排序

 * map排序 对map的key值进行排序
 * @param map 
 * @param sortFunc  
 * eg:
 * let map = {
 * key1: { name: 'wdf', sortid: 10 },
 * key2: { name: 'wwx', sortid: 1 },
 * key3: { name: 'sss', sortid: 5 },
 * }
 *  map = sortMap(map, (a, b) => { return a.sortid - b.sortid })
 */
function sortMap(map: {}, sortFunc?: (v1, v2) => number) {
    let keys = Object.keys(map)
    let sortkeys = keys.sort(sortFunc)
    let sortMap = {}
    sortkeys.forEach(k => { sortMap[k] = map[k] })
    map = sortMap
    return map
}

7.js中get请求中将json格式的对象拼接成复杂的url参数

const queryStr = Object.keys(query)
            .reduce((ary, key) => {
                if (query[key]) {
                    ary.push(encodeURIComponent(key) + '=' + encodeURIComponent(query[key]));
                }
                return ary;
            }, [])
            .join('&');
url += `?${queryStr}`;

8.前端js几种加密/解密方法

9.Promise和Async/await的理解和使用

https://www.wolai.com/x3SycgxN1kUXKjrUA2y4jh#7Le4q5RCZcGfeRF2N6NrMR

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容