鸿蒙JS开发项目总结

2022-01-20  本文已影响0人  Amok校长

第一部分 鸿蒙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(服务卡片)

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

// 在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

上一篇下一篇

猜你喜欢

热点阅读