美文网首页
鸿蒙JS开发项目总结

鸿蒙JS开发项目总结

作者: Amok校长 | 来源:发表于2022-01-20 16:28 被阅读0次

    第一部分 鸿蒙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

    相关文章

      网友评论

          本文标题:鸿蒙JS开发项目总结

          本文链接:https://www.haomeiwen.com/subject/ffwjhrtx.html