quickapp_快应用

news2024/10/6 16:16:58

目录

    • 官网
    • 概述
    • 开发前提
      • [1] 安装IDE
        • 问题-IDE打开是英文
      • [2] 创建项目
      • [3] 运行项目
      • [4] 项目结构
    • 开发调试
      • USB真机调试
      • 扫码调试
    • 上传发布
      • 步骤
      • error: 版本号必须高于上一个版本的
    • 页面(文件)
      • 组件
        • 快应用组件
          • 常用总结
          • 快应用组件
          • 第三方组件库
        • 页面级组件
        • 自定义组件(子组件)
          • 引入自定义组件(子组件)
          • 父组件给子组件传值
          • 子组件给父组件进行传值
      • js
        • 快应用全局对象global
        • this--vm实例化对象
        • 事件
        • 数据定义
        • 计算属性
        • 页面切换
          • 声明式导航
          • 路由跳转
          • 路由传参
          • 接收参数
          • 回传参数
        • app.ux
          • APP的生命周期
          • 公共方法- $app && $app. $def
            • 封装-缓存数据
          • 全局数据- $app. $data
          • 退出快应用-$app.exit
        • manifest配置文件
          • 应用包名-package
          • 应用名称-name
          • 应用图标-icon
          • 应用版本名称、应用版本号- versionName、versionCode
          • 路由配置-router
        • 页面的生命周期
          • 页面栈
          • 生命周期
          • 组件的生命周期
        • 通用方法
          • $element
            • 获取某元素的宽高
        • 系统接口
          • [1] 检查某app是否在手机上安装
          • [2] 下载应用
          • [3] 检查当前是否有桌面应用
          • [4] 添加桌面应用
          • [5]数据存储
          • [6]弹框
          • [7] 接口
          • [8]获取设备信息
        • h5跳转到快应用
          • deeplink
          • h5点击组件
          • url配置跳转
          • 总结
        • 逻辑问题
          • window is not defined
      • 样式问题
        • 引入css样式文件
        • [1]选择器
        • [2]盒模型
        • [3]样式布局-弹性布局
        • [4-1]样式切换 - 类名的动态切换
        • [4-2] 样式切换 - 行内样式动态切换
        • [5]background
        • [6]overflow
        • [7]border-radius
        • [8]盒子阴影
        • [9] 单位
        • [10] 定位

官网

快应用官网

概述

在这里插入图片描述

从上述可以看出 快应用的覆盖面比较窄,仅支持10种手机型号,像iPhone、三星等都是不支持快应用的~。但是快应用的优势还是比较明确的无需安装、即点即用,用完即走,简单来说就是比较方便,可以提升用户体验度。用户可以在 URL 链接、全局搜索、应用商店、浏览器、负一屏、系统桌面、PUSH、语音助手、安全中心、垃圾清理、信息助手、天气、短信模板、日历、个性主题、文件管理等等任何地方作为入口打开快应用…

在这里插入图片描述

开发前提

[1] 安装IDE

开发快应用的前提就是安装快应用开发工具

问题-IDE打开是英文

第一次打开时显示为英文是因为配置还没有加载好,关闭之后重新打开显示的就是中文了。

[2] 创建项目

在这里插入图片描述
点击如上新建项目打开新建工程界面
在这里插入图片描述

新建工程界面展示如上,可以选择快应用快应用卡片快应用(Webview) 三类项目

选择某一模版,点击下一步,项目创建完成。

[3] 运行项目

如果您基于官方模版,创建新项目,需要先安装依赖,才能正常运行。您可以使用 yarn 或 npm i 命令,在终端运行来安装依赖,然后运行项目。

也可点击下图的 安装依赖重新启动编译来启动项目(其实就是快捷键)。
在这里插入图片描述

[4] 项目结构

> └── src
│   ├── assets          # 公用的资源(Images/Styles/字体...)
│   │   ├──images       # 存储 png/jpg/svg 等公共图片资源
│   │   └──styles       # 存放 less/css/sass 等公共样式资源
│   ├── helper          # 项目自定义辅助各类工具
│   ├── pages           # 统一存放项目页面级代码
│   ├── app.ux          # 应用程序代码的入口文件
│   └── manifest.json   # 配置应用基本信息
└── package.json        # 定义项目需要的各种模块及配置信息

开发调试

在开发过程中,快应用运行效果,会在主界面右侧的模拟器中显示。

但是模拟器中运行的效果和真机存在差异

  • UI: 很多UI在模拟器上显示正确但是在真机上显示错乱
  • API: 模拟器尚未支持全部 API

因此实际开发过程中还需要使用真机来预览,来调试快应用的实际运行情况。

USB真机调试

  • 前提:准备一台安卓手机,确保手机处于开发者模式

    若是不确定手机是否处于开发者模式: 设置 -> 关于手机 -> 软件版本 -> 多次点击软件版本号至提示“您已处于开发者模式,无需进行此项操纵”为止

  • 步骤

    [1] 使用数据线连接电脑与手机

    确保数据线可以传输数据而不是只能用于充电;否则会报错–> 找不到Android

    [2] 点击 IDE 工具栏的「USB 调试」开始调试

    每次运行调试时,开发者工具会检测您的手机是否安装了【快应用预览版】【快应用调试器】。如果未安装,开发者工具将自动安装。 若是已安装会自动打开快应用预览版进入快应用首页进行调试,与此同时电脑端会打开调试页面。

扫码调试

  • [1]在快应用调试器下载地址: 官网->开发支持->开发工具->帮助中心->资源下载下载快应用调试器 与 快应用预览版;
  • [2] 点击如下二维码icon打开二维码并使用快应用调试器扫描二维码可正常在手机上进行调试
    在这里插入图片描述

上传发布

步骤

  • 打包: 点击顶部工具栏的打包按钮

    若无签名,会索引您添加签名
    在这里插入图片描述
    在这里插入图片描述
    点击完成之后会自动在项目根目录生成一个sign文件里面存储签名。
    在这里插入图片描述

    若是存在签名:快应用开发工具将自动生成 release 签名的包,既可以直接使用rpk包上传至官网也可上传包管理平台,如下:
    在这里插入图片描述

  • 包管理平台: 在打包完成之后可以点击上传包管理平台上传本次rpk文件,上传成功之后会出现一个二维码和包管理平台的链接,您可使用调试器的扫码功能,打开此快应用
    在这里插入图片描述

  • 上传至官网:在开发完成之后,若您想发布上线该快应用,可以通过快应用开发工具的「上传」功能,将其上传至官网的开发者中心,后续可在官网按照流程填写相关信息后,发布上线快应用(当然,您也可以在后台,手动提交 RPK 包)

error: 版本号必须高于上一个版本的

问题: 在更新版本上传rpk文件时,提示版本号必须高于上一个版本

原因:出现这个问题的原因是快应用官方以配置 manifest.json 的属性versionCode的值来确认版本更新,官方要求每次上架更新需要将该值手动 自增1。很多同学会误以为修改 versionName 来更新版本,versionName 应该是属于那种显示在应用商店的版本号!

我就是在版本迭代时只是修改了versionName属性值但是没有修改versionCode属性的值,因此在发布时一直提示“版本号必须高于上一个版本”。

页面(文件)

现在回想一下Vue页面构成

<template>
  <!-- template里只能有一个根节点 -->
  <!-- 可以是原生html,或是基于html封装的一些组件-->
</tempalte>
<script>
  export default{
    // 配置项
  }
</script>
<style lang='less/scss'>
  css/less/scss
</style>

ux文件与vue文件结构完全相同,但是语法有所区别

  • [1] 快应用不支持原生HTML,开发快应用只能使用快应用组件和基于快应用组件封装的组件;
  • [2] 快应用的样式使用的也是css,但是存在很多样式兼容问题,需要后面一一记录

    兼容性问题产生的原因是:每个快应用组件支持的样式不一样,我们如果一直按照使用原生HTML的思维去使用快应用组件,就会感觉某些样式不起作用了,就会感觉存在某些兼容性问题!

  • [3] 快应用的逻辑使用也是ECMAScript,不包含BOM与DOM

组件

快应用组件

在快应用中不支持使用原生html —> 若是使用原生html直接不显示

因此在开发快应用时只能使用快应用组件~比如div、text…

此时需要注意的是:这些组件不是原生html标签,在使用时需要关注组件支持的样式、事件以及是否能存放文本

举例说明

  • 接受子组件
    在这里插入图片描述

  • 接受的样式
    在这里插入图片描述

  • 是否支持存放文本
    在这里插入图片描述

  • 检查

    因此当渲染结果和自己想象的不同时可以直接查看官网文档说明。

    也可在控制台输出里面查看提示
    在这里插入图片描述

常用总结
  • [1] 文本必须包裹在span/a/text组件中,否则不显示
  • [2] span必须作为text/a/span组件的子组件,否则不显示;
快应用组件

常用的快应用组件

第三方组件库
  • https://vivoquickapp.github.io/apex-ui-docs/
  • https://jdsecretfe.github.io/quist-ui/
  • https://quickappcn.github.io/qaui/
页面级组件

pages中定义的组件被称为页面级组件。

页面级组件(等同于Vue页面),通过路由配置可以进行页面跳转。

自定义组件(子组件)

components中定义的组件被称为自定义组件。

自定义组件(等同于Vue的子组件),将使用比较多的部分进行封装,可以多次使用。

引入自定义组件(子组件)

在这里插入图片描述
举例说明
在这里插入图片描述

父组件给子组件传值
  • 父组件给子组件传值使用的是props,其语法与vue 的props传值类似,可以规定传值类型、默认值等,还可以进行数据校验
    • 在父组件给子组件进行传值时使用的是短横线分割命名,在子组件中通过props 接收时使用的是驼峰命名

    • 子组件接收属性时,可以设置默认值。当调用子组件没有传入该数据时,将会自动设为默认值。

    • 父子间的数据传输是单向性的,父组件 prop 数据更新,子组件的数据会刷新为最新值;子组件的 prop 值发生改变,并不会改变父组件中值。但是prop 类型事数组或者对象,自组件变化会影响到父组件的值,这意味着你不应该在一个子组件内部改变 prop 的值,这是危险性操作。

    • 在进行校验时,验证顺序是 必填项检查 -> 类型检查 -> 函数检查

    • 语法

      props: {
        prop1:  [String、Number、Boolean、Function、Object、Array], // 仅类型检查
      prop2Object: {
        type:  [String、Number、Boolean、Function、Object、Array], // 类型检查
        required: true, // 必填项检查
        validator: function(value) {
          return true // 符合检查
          return false // 不符合检查
        }
      }
      
    • 举例说明: 在父组件接收三个参数分别为name( 字符串类型且必传),年龄(数字类型,只能接受18,19,29三个中的某一个数字),地址(字符串类型,不能超过18个字, 默认为中国)并将展示在页面上

      父组件

      <import name='son' src='../../components/son.ux'></import>
      <template>
        <div>
          <son p-name="{{name}}" p-age="{{age}}"></son>
        </div>
          
      </template>
      <script>
      export default{
        private: {
          name:'chaochao',
          age:'20'
        }
      }
      </script>
      

      子组件

      <template>
         <div>
           <text>{{pName}}</text>
           <text>{{pAge}}</text>
           <text>{{pArea}}</text>
         </div>
       </template>
       <script>
       export default{
         data(){
           return{
             name:'子组件'
           }
         },
         props: {
           pName: {
             type: String,
             required: true
           },
           pAge: {
             type: Number,
             required: true,
             validator: function(value) {
               return [18, 19, 20].includes(value)
             }
           },
           pArea: {
             type:String,
             default:'中国',
             validator: function(value) {
               return value.length<18
             }
           }
         },
       }
       </script>
      

      此时页面能正常显示内容 chaochao20中国,但是控制台会报出警告如下:
      在这里插入图片描述

子组件给父组件进行传值

在这里插入图片描述
语法

// 子组件
this.$dispatch('子组件触发事件名',)
// 父组件
onInit(){
  this.$on('子组件触发事件名',触发的父方法方法)
}
// 子组件
this.$emit(方法名,值)
// 父组件
<son on方法名=‘父组件方法’></son>

举例说明:在子组件修改父组件传过来的name属性

  • 方式1

    • 子组件:触发父组件自定义事件
      editname(){
        this.$dispatch('dispatchEvt',{
          name:'niuniu'
        })
      }
      
    • 子组件:监听自定义事件触发
      onInit(){
        this.$on('dispatchEvt',this.editName)
      },
      editName(value){
        console.log(value)
      }
      
      打印结果如下:
      在这里插入图片描述
      因此我们可以通过如下方式进行赋值
      editName(value){
       this.name = value.detail.name
      }
      
  • 方式2

    • 子组件
      editname(){
        this.$emit('editName',{
          name:'niuniu'
        })
      }
      
    • 父组件
      <son p-name="{{name}}" p-age="{{age}}" onedit-name='editname'></son>
      
      editname(value){
        console.log(value)
      }
      
      打印结果如下:
      在这里插入图片描述
      因此我们可以通过如下方式进行赋值
      editName(value){
       this.name = value.detail.name
      }
      

tips: 当传递结束后,可以调用value.stop()来结束传递,否则会一直传递下去

js

快应用全局对象global

在快应用中不能使用BOM、DOM,因此也不能使用window作为全局对象。

在快应用中可以使用global访问全局对象
在这里插入图片描述

在快应用中global对象可以直接使用,我们可以将封装的公共方法添加在global对象上(类似于将封装的公共方法添加在vue实例化对象上)。

this–vm实例化对象

this指向的是vm实例化对象(使用与vue2.x中相同)。

事件

在快应用上进行事件绑定与vue2.x中相同(唯一的区别是在vue2.x中是将方法定义在methods配置项中,定义在methods配置项中的方法会被平铺在实例化对象上;而快应用中是直接将定义的方法平铺在实例化对象上–不定义在methods配置项中)
在这里插入图片描述

数据定义

定义数据时:页面级组件定义数据时可以根据需要将数据定义在data、public、protected、private属性中(data不可与public、protected、private同时存在),而自定义组件中数据模型只能使用data 属性
在这里插入图片描述
在这里插入图片描述

计算属性

计算属性

页面切换

官网

声明式导航

在快应用中可以通过 a组件(类似vue中的link组件)进行声明式导航,不仅可以跳转到站内页面、还可以通过webView加载网页、掉起电话、短信、邮件…

<template>
  <div class="wrapper">
    <a href="/pages/Home">去首页1</a>
    <a href="pages/Home">去首页2</a>
    <a href="tel:10086">打电话</a>
    <a href="sms:10086">发短信</a>
    <a href="mailto:example@xx.com">发邮件</a>
    <a href="https://www.baidu.com/">打开webView加载网页</a>
  </div>
</template>
路由跳转

在快应用中是通过router接口进行路由跳转的(类似vue中的router)

router接口提供一下几个方法进行路由跳转

router.push方法
router.push(OBJECT)支持的参数 uri 与组件 a 的 href 属性完全一致

router.replace方法
router.replace(OBJECT)的支持的参数 uri 不支持调起电话、短信、邮件,其他与 push 一致

router.back方法返回上一级

router.clear方法清空历史记录仅保留当前页面

<template>
  <div class="wrapper">
    <text @click='jump(1)'>去首页1</text>
    <text @click='jump(2)'>去首页2</text>
    <text @click='jump(3)'>打电话</text>
    <text @click='jump(4)'>发短信</text>
    <text @click='jump(5)'>发邮件</text>
    <text @click='jump(6)'>打开webView加载网页</text>
  </div>
</template>

<script>
import router from '@system.router'
export default {
  jump(type){
    let uri =''
    switch(type){
      case 1:
        uri = '/pages/Home'
        break;
      case 2:
        uri = 'pages/Home'
        break;
      case 3:
        uri = 'tel:10086'
        break;
      case 4:
        uri = 'sms:10086'
        break;
      case 5:
        uri = 'mailto:example@xx.com'
        break;
      case 6:
        uri = 'https://www.baidu.com/'
        break;
    }
    router.push({
      uri
    })
  }
}
</script>
路由传参

使用a组件或router接口进行路由跳转时----传递参数与接口参数方式一致,在此以router.push方法进行说明。

  • 若是通过a组件进行路由跳转时可以通过在uri上拼接**?key=value**的形式进行路由传参
    <a src='xxx?key1=value1&key2=value2'>路由跳转</a>
    
  • 若是通过router接口进行路由跳转则有两种方式
    router.push({uri:'xxx?key1=value1&key2=value2'})
    
     router.push({
     uri: 'xxx',
     params:{
       key1: value1,
       key2: value2
     }
     })
    
接收参数
  • 路由跳转
    jump(type){
      router.push({
        uri: '/pages/Home',
        params: { value: 222222 }
      })
    }
    
  • 目标页面接收: 需要先在public或protected中定义key名相同的属性,否则接收不到!
    在这里插入图片描述
    onReady() {
      console.log(this.value) // 不先定义接收不到undefined
    }
    
    public:{
      value: ''
    },
    onReady() {
      console.log(this.value) // 222222
    } 
    

    protected 内定义的属性,允许被应用内部页面请求传递的数据覆盖,不允许被应用外部请求传递的数据覆盖

回传参数

可以通过在 app 中增加缓存的数据,并提供读写缓存数据的能力来实现。

封装缓存数据方法

app.ux
APP的生命周期

App的生命周期在app.ux 中定义的回调函数。

onCreate() {
  prompt.showToast({
    message: 'onCreate--应用调用--onCreate'
  })
},
onRequest(){
  prompt.showToast({
    message: 'onRequest--监听应用收到一个外部的打开新页面的请求--onRquest'
  })
},
onShow(){
  prompt.showToast({
    message: 'onShow--应用返回前台时调用--onShow'
  })
},
onHide(){
  prompt.showToast({
    message: 'onHide--应用退到后台时调用--onHide'
  })
},
onDestroy(){
  prompt.showToast({
    message: 'onDestroy--应用销毁时调用--onDestroy'
  })
},
onError({message}){
  prompt.showToast({
    message: 'onError--应用报错时调用--onError'+`错误原因是${message}`
  })
}

上述代码

  • 进入系统时走: onCreate、onRequest、onShow;
  • 通过router.push进行页面跳转时不走任何回调
  • 切换后台时走: onHide
  • 切回项目时走:onShow
  • 存在错误时走: onError
公共方法- $app && $app. $def

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

// 公共方法文件
export default {...}
//app.ux文件
<script>
//import utils from './helper/utils'
const utils = require('./helper/utils').default
export default{
 utils
}
</script>
// 其他ux页面
this.$app.$def.utils // 可以获取到处的公共对象

[2] 另外一些公用方法也可以直接声明在app.ux中,这些方法也可以通过this.$app. $def.方法名去使用, 也可以通过 this. $app. 方法名直接使用!

[3] 在app.ux中定义的数据如下

data:{
  text: 111
}

也可以通过this.$data. $def.data.text, 此时获取的值为111。

封装-缓存数据
//获取 app 缓存的数据
getAppCache (key) {
  return this.dataCache ? (this.dataCache[key] || '') : ''
},
// 设置 app 缓存的数据
setAppCache (key, val) {
  if (val === '' && this.dataCache[key]) {
    delete this.dataCache[key]
    return
  }
  this.dataCache[key] = val
},
clearAppCache () {
  this.dataCache = {}
}

使用直接通过$app去使用即可。

this.$app.setAppData()
全局数据- $app. $data

在实际开发过程中,若是存在一些常量切在项目的多个地方使用时,可以将该数据存储在manifest.json配置项的config.data中。

在使用时可以通过$app.$data去获取。

退出快应用-$app.exit
this.$app.exit() // 退出开应用,结束应用生命周期
manifest配置文件

manifest配置文件1-配置信息
manifest配置文件2

应用包名-package

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

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

{
  "package": "com.example.demo"
}
应用名称-name

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

{
  "name": "发票小助手"
}
应用图标-icon

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

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

在上传时显示的图标img即为此处的图标。

应用版本名称、应用版本号- versionName、versionCode

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

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

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

示例如下:

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

在上传时版本以versionCode为准,在应用商店展示的版本号以versionName为准

路由配置-router

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

  • entry:表示首页名称,若是没有配置entry属性默认pages第一个为首页路径。
    "router":{
      "entry": "首页页面目录名"
    }
    
  • pages: 页面配置列表
    "router":{
      "pages": {
        "页面目录名": {
          "component": "与 ux 文件名保持一致"
        }
      }
    }
    

注意事项

  • [1] 一个目录下最多只能存在一个主页面文件(不包括组件文件)

    src
      — pages
              — Test
                     — test.ux
                     — test2.ux

    如上文件在Test中存在 test.ux、test2.ux两个ux文件,但是这两个文件不能都作为主页面文件,因为一个目录下最多只能存在一个主页面文件!

    "router":{
       "pages/Test": {
          "component": "test",
          "path": "/test1"
        },
        "pages/Test": {
          "component": "test2",
          "path": "/test2"
        }
    }
    

    此时会报错 Duplicate object key(重复配置)

    若是想给这两个文件设置路由

    src
      — pages
              — Test
                     — test.ux
                     — test2
                         — test2.ux

    "router":{
       "pages/Test": {
          "component": "test",
          "path": "/test1"
        },
        "pages/Test/Test2": {
          "component": "test2",
          "path": "/test2"
        }
    }
    
页面的生命周期
页面栈

web页面开发:在浏览器页签中每次只能有一个页面,当前页签打开另一个页面,上个页面就销毁了;
在浏览器页签打开某个页面1(页面1初始化、渲染…),在当前页签打开页面B(页面1销毁,页面2初始化、渲染…)

快应用开发:可以同时运行多个页面,但是每次只显示其中一个页面

页面栈中就是存储当前打开的页面!

生命周期
组件的生命周期

生命周期

  • onInit:数据已经准备好,可以开始使用页面中的数据
  • onReady: 模板已经编译完成,可以获取dom节点
  • onShow: 页面重新显示时调用
  • onHide: 页面被隐藏时调用
  • onDestory: 页面被销毁时调用
  • onBackPress
  • onMenuPress
  • onRefresh
  • onConfigurationChanged
  • onReachTop
  • onReachBottom
  • onPageScroll
通用方法

通用方法,即提供给所有组件调用的方法。

$element

获取指定 id 的组件 dom 对象,如果没有指定 id,则返回根组件 dom 对象用法。

this.$element('id名')
获取某元素的宽高
const element =  this.$element('元素id名')
element.getBoundingClientRect({
   success: data =>{
     // data中包含元素的宽高 ,left\right\bottom\top
   }
 })
系统接口

在项目中使用到的接口都需要在配置文件manifest.json中声明,不然会报如下警告

[WARN] 请在 manifest.json 文件里声明项目代码中用到的接口: system.storage, service.account, system.package, system.webview
[1] 检查某app是否在手机上安装
  • 官方文档:官方文档
  • 接口: system.package的hasInstalled方法
  • 作用:检查某app是否在已经在手机上安装
  • 使用
    • [1] 接口声明- 在配置文件manifest.json中声明
      "features": [
        {
          "name": "system.package" 
        },
      ]
      
    • [2] 在需要的地方导入并使用
        import pkg from '@system.package'
      
      pkg.hasInstalled({
        package: 'app包名',
        success: function(data) {
          console.log(`handling success: ${data.result}`)
          // result为true表示app已安装
          // result为false表示app未安装
        },
       fail: function(data, code) {
         console.log(`handling fail, code = ${code}`)
        }
      })
      
[2] 下载应用
  • 官方文档:官方文档
  • 接口: system.package的install方法
  • 作用:下载某app
  • 使用
    • [1] 接口声明- 在配置文件manifest.json中声明
      "features": [
        {
          "name": "system.package" 
        },
      ]
      
    • [2] 在需要的地方导入并使用
      import pkg from '@system.package'
      
      pkg.install({
       package: '应用包名',
       success: function(data) {
         console.log(`handling success: ${data.result}`)
         // result:true 下载成功
         // result: false 下载失败
       },
       fail: function(data, code) {
         console.log(`handling fail, code = ${code}`)
       }
      })
      
[3] 检查当前是否有桌面应用
  • 官方文档:官方文档
  • 接口: system.shortcut的hasInstalled方法
  • 作用:检查某app当前是否有桌面应用
  • 使用
    • [1] 接口声明- 在配置文件manifest.json中声明
      "features": [
        {
          "name": "system.shortcut" 
        },
      ]
      
    • [2] 在需要的地方导入并使用
      import shortcut from '@system.shortcut'
      
      shortcut.hasInstalled({
       success: function(res) {
         // res 为true表示已创建图标
         // res weifalse表示未创建图标
       }
      })
      
[4] 添加桌面应用
  • 官方文档:官方文档
  • 接口: system.shortcut的install方法
  • 作用:为某app添加桌面应用
  • 使用
    • [1] 接口声明- 在配置文件manifest.json中声明
      "features": [
        {
          "name": "system.shortcut" 
        },
      ]
      
    • [2] 在需要的地方导入并使用
      import shortcut from '@system.shortcut'
      
      shortcut.install({
        success: function() {
          console.log('handling success') // 创建成功
        },
        fail: function(data, code) {
         // 创建失败,请在设置中开启创建桌面应用权限
         console.log(`handling fail, code = ${code}, errorMsg=${data}`)
        }
      })
      
[5]数据存储
  • 官方文档:官方文档
<template>
  <div class="wrapper">
    <text id='text' @click='setValue'>存储数据</text>
    <text id='text' @click='getValue'>获取数据</text>
  </div>
</template>

<script>
import storage from '@system.storage'
import prompt from '@system.prompt'
export default {
  setValue(){
    storage.set({
      key: 'test',
      value: '11111',
      success: function(data) {
        prompt.showToast({
          message: '存储成功'
        })
      },
      fail: function(data, code) {
        console.log(`handling fail, code = ${code}`)
      }
    })
  },
  getValue(){
    storage.get({
      key: 'test',
      success: function(data) {
        prompt.showToast({
          message: data
        })
      },
      fail: function(data, code) {
        console.log(`handling fail, code = ${code}`)
      }
    })
  }
}
</script>
[6]弹框
  • 官方文档:官方文档
  • 弹出框一共有三种
    • toast提示框-showToast
    • dialog对话框-showDialog
    • 列表框-showContextMenu
[7] 接口
  • 官方文档:官方文档
  • 请求封装
    import { fetch } from "@system.fetch";
    import { getStorage, setStorage } from './storage'
    const api = 'xxx' 
    
    const hasToken = async () => {
       const token = await getStorage('token')
       return !!token
    }
    
    // 将与后端约定的数据统一添加在请求头中
    const getHeaders = async () => {
       const token = await getStorage('token')
       return {
           token,
           ....
       }
    }
    
    export const httpGet = async (url, data = {}, header = {}) => {
     await hasToken()
     const headers = await getHeaders()
     return new Promise((resolve, reject) => {
       fetch({
         url: api + url,
         data,
         method: 'GET',
         responseType: 'json',
         header: {
           ...headers,
           ...header
         },
         success(data) {
           resolve(data.data)
         },
         fail(err) {
           reject(err)
         }
       })
     })
    }
    
    export const httpPost = async (url, data = {}, header = {}) => {
     await hasToken()
     const headers = await getHeaders()
     return new Promise((resolve, reject) => {
       fetch({
         url: api + url,
         data,
         method: 'POST',
         responseType: 'json',
         header: {
           ...header,
           ...headers
         },
         success(data) {
           if (data.data.status === 1004) {
             router.replace({
               uri: '/pages/Login'
             })
           } else {
             resolve(data.data)
           }
             
         },
         fail(err) {
           reject(err)
         }
       })
     })
    }
    
    export default {
     httpGet,
     httpPost
    }
    
    
[8]获取设备信息

获取设备信息 如屏幕高度

h5跳转到快应用

首先并不是所有机型都支持在h5页面跳转到快应用页面的,因此在进行跳转之前需要先判断当前机型是否支持跳转做好兜底。

h5跳转到快应用有以下几种方式

deeplink

可以通过deeplink的形式进行跳转

  • deeplink支持格式如下:

    • http://hapjs.org/app/<package>/[path][?key=value]
    • https://hapjs.org/app//[path][?key=value]
    • hap://app//[path][?key=value]
  • 参数如下:

    • package: 应用包名(与manifest.json中package属性相同),必选
    • path: 应用内页面的 path,可选,默认为首页
    • key-value: 希望传给页面的参数,可选,可以有多个
  • 快应用内参数获取: 快应用内会自动获取key-value并赋值给public内的同名参数

    • 注1:若是public内不同名参数,则不会新增这个属性 -> 相当于没有获取这个参数
    • 注2: 不同的厂商对该能力可能有不同限制,使用前请和相应厂商确认(本人试了华为、荣耀、小米、OPPO的几部测试机,目前并没有发现问题)
  • 举例说明

    <script type="text/javascript" src="//statres.quickapp.cn/quickapp/js/qa_router.min.js"></script>
    

    在网页嵌入如上js后,会给window对象添加一个方法channelReady,可以通过这个方法检验当前机型是否支持跳转;

    clickmethod(){
      if (window.channelReady) {
        window.channelReady(function (bAvailable) {
          // 允许跳转
          if (bAvailable) {
            location.href = `https://hapjs.org/app/com.klang.benz/pages/Front?phone=${_this.phone}&channel=${_this.channel}`
          }else{
            // 不允许跳转- 兜底
            // 下载对应app
          }
        }
      }else{
        //  下载对应app
      }
    }
    
    
h5点击组件

h5点击组件是指:网页开发者可以在其H5 页面中使用快应用官方推荐的点击组件,用于跳转指定快应用。使用点击组件时,必须由用户主动点击方可发起跳转快应用请求。

  • 在网页嵌入如下 js:
    <script type="text/javascript" src="//statres.quickapp.cn/quickapp/js/qa_router.min.js"></script>
    
    在网页嵌入如上js后,会给window对象添加一个方法channelReady,可以通过这个方法检验当前机型是否支持跳转;
    在网页嵌入如上js后,会有一个全局组件 ,可以在页面合适位置插入(样式可自行调整),组件属性如下
    在这里插入图片描述

    tips: 虽然官方文档上说会将参数赋值给public同名属性,但是在真机上很多型号接收不到参数!!!

url配置跳转

官方文档不推荐使用url配置跳转方式进行跳转
在这里插入图片描述

  • 在网页嵌入如下js文件
    <script type="text/javascript" src="//statres.quickapp.cn/quickapp/js/routerinline.min.js"></script>
    
    嵌入之后会在window上添加appRouterchannelReady方法,其中channelReady用来检验是否可以跳转,appRouter方法用来进行跳转,具体语法请看文档。
总结

在进行快应用开发时我最先使用的是“h5点击组件跳转”,然后发现参数都接收不到,因此我就尝试了“deeplink”方式进行跳转,万幸~这次可以成功拿到参数。

但是此时出现了一个新的问题:有的手机点点击跳转中间页的“手动打开”不起作用,如下
在这里插入图片描述
流程相当于被卡在这里了…
但是同样的跳转地址我在快应用预览版->启动应用测试->Deeplink启动测试里面进行跳转就可以成功打开,如下:
在这里插入图片描述
让我不禁怀疑是不是h5里面的跳转写的有问题,经过一番测试发现是浏览器的问题,只有手机自带的浏览器才有下面这个请求提示!!!

总结: 有的机型在点击手动打开时就可跳转到快应用,而有的手机型号点击时无反应,若是在手机自带浏览器会弹出下面打开快应用中心提示,若是其他浏览器则会中断流程…

逻辑问题
window is not defined
  • 问题描述: 在快应用中使用window对象在预览时并没有报错,但是在真机调试时报错 window is not defiend

  • 原因:window对象是相对于Web浏览器而言的,它并不是ECMAScript内置对象,它是浏览器的Web API。

    而快应用并不是在浏览器中打开而是在node环境中打开,因此不能使用window以及window的属性/对象。

    快应用只使用js的语法只能使用ECMSSCript,不能使用BOM、DOM。

样式问题

就像之前所说的,所谓样式兼容性问题是因为我们一直将快应用组件当作原生html标签使用。

接下来就是按照我们之前编写web页面的一些习惯 针对一些不兼容样式进行说明~

引入css样式文件
@import './style.css';
[1]选择器
  • 支持标签选择器、类选择器、id选择器,暂不支持其它选择器;
  • 继承:不支持样式继承;
[2]盒模型

快应用布局框架使用 border-box 模型,暂不支持 手动指定 box-sizing 属性(快应用中只能使用border-box 盒模型不能使用content-box盒模型)。

[3]样式布局-弹性布局

在快应用中组件默认采用的都是 弹性布局的方式进行布局。

  • 弹性布局不可以取消 ! ===> 在快应用中display只有flex与none取值情况,

      display: flex ; // 弹性布局
      display: none; //  消失
    
  • 若是不想子元素在一行排列 可以使用修改主轴方向

      flex-direction: column;
    
  • 注意:在弹性布局中 ===> 若是子元素的高度/宽度总和大于父元素的高度或宽度,不会出现滚动条,而是子元素的宽/高 收缩。

    若是需要使用滚动条,可以使用list组件!

[4-1]样式切换 - 类名的动态切换

在很多情况下,我们需要通过动态切换类型来改变元素的的样式,在快应用中注意,切换类名时,类名必须在目标元素上,不然没效果!
比如设置在父元素上

.active{
  text{
    color: red; // 没效果
  }
}

我给text的父元素添加active类名然后修改text元素文本的颜色,但是发现没有效果;但是把类名动态添加在text标签上就发现样式可以正常切换了。

.active{
  color:red;
}
[4-2] 样式切换 - 行内样式动态切换

行内样式不支持动态编写 ----> 可以使用computed或methods

 <div style='{{background-image:url(imgurl)}}' class='www'></div>
  private:{
    imgurl: 'https://martin-upload.wcar.net.cn/web/2021/11/6bbf95698459f15b0050cb0d8e9e3484.png'
  }

上述代码不能正常显示图片,个人猜测是因为识别不出变量imgurl,若是想样式中的数据动态切换,可以采用computed与methods

  <div style="{{returnStatusImage()}}"  class='www'></div>
private: {
   text: '快应用是什么?',
   status:0
},
returnStatusImage() {
   switch (this.status) {
     case 0:
       return 'background-image:url(https://martin-upload.wcar.net.cn/web/2021/11/6bbf95698459f15b0050cb0d8e9e3484.png)'
       break;
     case 1:
       return 'background-image:url(https://martin-upload.wcar.net.cn/web/2021/11/07167f84c6dbf2679a6b1744acdd6ae9.png)'
       break;
     case 2:
       return 'background-image:url(https://martin-upload.wcar.net.cn/web/2021/11/743cbd9439d241cb6c8af9aeb85b312e.png)' 
       break;
     case 3:
       return 'background-image:url(https://martin-upload.wcar.net.cn/web/2021/12/5459fe6f0978ca211dc7034b903547c2.png)'
       break;
     case -1:
       return 'background-image:url(https://martin-upload.wcar.net.cn/web/2021/12/5459fe6f0978ca211dc7034b903547c2.png)'
       break;
     case 4:
       return 'background-image:url(https://martin-upload.wcar.net.cn/web/2022/02/9ff11fe02d56737ed45dec1ff626a194.jpg)'
       break;
     default:
       return 'background-image:url(https://martin-upload.wcar.net.cn/web/2021/11/6bbf95698459f15b0050cb0d8e9e3484.png)'
   }
 },
[5]background
  • 在快应用中background属性的作用是用来设置渐变色的,不能作为背景的复合属性。
    • 起作用
      background: linear-gradient(53deg, #F0E6D5 0%, #F0DFC3 100%);
      
    • 无作用
      background: red;
      
    • 若是想设置颜色使用background-color
        background-color:red;
      
  • span组件添加背景色不起作用!若是想要设置背景色不要使用span组件(span不支持背景样式设置)
[6]overflow

在快应用中overflow可接受的属性值如下

overflow: visible; // 显示
overflow: hidden; // 隐藏

因此没有办法设置元素显示滚动条等

[7]border-radius

在快应用中border-radius只接受一个值作为属性值

  • 若是设置2/3/4个值,则会报出警告
    border-radius:30px 20px 10px 0; // 四个圆角都会设置为30px
    
    不支持30px 20px 10px 0作为单位,在编译时会将第一个值后面的值看作为单位
  • 设置4个一样的值
    border-radius:30px 20px 10px 0; // 四个圆角都会设置为30px
    
  • 若是想四个圆角弧度不一致
    border-top-left-radius:30px; // 左上
    border-top-right-radius:30px; // 右上
    border-bottom-left-radius:30px; //  左下
    border-bottom-right-radius:30px; // 右下
    
[8]盒子阴影

快应用中不支持盒子阴影。

[9] 单位

快应用中支持 px % dp单位;但是%单位在真机中显示不对!

[10] 定位

定位没有层级 ----> 存在被覆盖导致点击事件不起作用的现象

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1189041.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

国标28181-2022/GB28181-2022国标检测

最近两周带了几个人一起开发国标28181-2022的平台检测&#xff0c; 由于没有28181-2022设备&#xff0c;目前一所还没有一家平台检测过&#xff0c;所以压力比较大&#xff0c;不过还好把28181-2022平台全项检测顺利过了&#xff0c;还帮忙测出了检测中心NVR的几个bug。看了下这…

超全大厂UI库分享,可免费套用!

今天我们要给大家分享的是TDesign、Arco Design、Ant Design、Material design等6个优秀的大厂UI库&#xff0c;一次性打包送给大家&#xff0c;通通免费用。大厂UI库都是经过无数次的事件检验的&#xff0c;扛住了许多种使用场景和突发情况的组件资源库&#xff0c;是前人的经…

美型和微整形SDK技术解决方案的新时代

人们对于美的追求已经不仅仅局限于化妆和服装&#xff0c;更多的是希望通过科技手段来实现自然、健康的美。美摄科技&#xff0c;作为全球领先的智能影像技术提供商&#xff0c;一直致力于通过技术创新&#xff0c;满足人们对美的追求。我们推出了针对美型和微整形的SDK技术解决…

taro(踩坑) npm run dev:weapp 微信小程序开发者工具预览报错

控制台报错信息&#xff1a; VM72:9 app.js错误: Error: module vendors-node_modules_taro_weapp_prebundle_chunk-JUEIR267_js.js is not defined, require args is ./vendors-node_modules_taro_weapp_prebundle_chunk-JUEIR267_js.js 环境&#xff1a; node 版本&#x…

怎么经营朋友圈?

朋友圈就是现代人的社交场&#xff0c;朋友圈发布的好坏会直接影响你的人际关系。怎么经营朋友圈&#xff1f;这个问题大部分人都不太知道&#xff0c;今天我们就来说说。 一、常见朋友圈&#xff1a; 1、广告型朋友圈 现在的朋友见到的&#xff0c;大部分都是每天发十多条的…

网站引流绝技:如何通过外链持续给网站带来高质量流量

做网站的人&#xff0c;不论是写文章还是搞外链&#xff0c;最终都是希望能获得更多的流量。既然是为了搞来流量和收入&#xff0c;你可能还不知道有一种方法既能搞来外链还能带来源源不断的高质量流量。 这个方法我在8年前就已经掌握&#xff0c;而且至今我仍认为它是一种有效…

上传文件大小限制报错

做了一个上传文件的功能&#xff0c;前端通过文件流程的形式调用后台接口。几百k的文件能成功&#xff0c;几M的文件会失败。原因有二 第一是被nginx限制&#xff0c;请求也无法转发到应用服务器里面&#xff08;也就是tomcat看不到请求日志只有nginx日志能看到请求&#xff0…

企业如何实现高效运转?工单管理系统有什么特点和优势?

在当今这个数字化、信息化的时代&#xff0c;企业需要一个高效、智能的工具来优化和协调内部和外部的工作流程。工单管理系统正是这样一个不可或缺的软件工具&#xff0c;它能够自动化、智能化地处理工单&#xff0c;提高工作效率和客户满意度。本文将详细介绍工单管理系统的特…

国标28181-2022检测内容GB28181-2022检测内容

目前国标28181-2022平台全项检测一共181项&#xff0c;总的检测相对2016版本要复杂很多&#xff0c;增加了一些比较重要的功能,下面列举下检测项(qq 123011785):

征服地球极限,中国极地科考与登峰事业的“御寒”之旅

7日&#xff0c;全国各地大幅降温&#xff0c;今年第一场暴风雪也席卷了黑龙江。 伴随着冷空气不断入侵&#xff0c;气温持续走低&#xff0c;寒冬的脚步越来越近&#xff0c;供暖也成为了北方地区的冬季重点民生课题。 是日&#xff0c;天色未晓&#xff0c;黑龙江各地身披红…

C语言 做一个学生信息管理系统

#include<stdio.h> #include<string.h> #include<stdlib.h> typedef struct person {char name[30];char sex[10];int num;struct person *next; }stu; stu *head NULL; void printf_link(stu *head) {stu *pd head;while(pd ! NULL){printf("姓名&a…

单应用多语言切换(语言国际化)

目录 编写语言管理类 编写Activity 的父类 DEMO 实验界面--首页Activity DEMO 实验界面--设置语言Activity Demo 语言资源文件 参考连接 编写语言管理类 package com.example.languageapplicationimport android.content.Context import android.content.ContextWrapper i…

code:-9907磁盘不足如何处理?帮你整理了几个必备的!

错误代码-9907表示磁盘空间不足。这意味着您的设备上的磁盘空间不足以完成当前的下载或存储任务。我们可以用这些方法解决这个问题。 一、对大文件进行压缩 可以使用压缩软件将一些文件进行压缩&#xff0c;以减少它们占用的磁盘空间。下面以嗨格式压缩大师作为操作示例。 1、…

URI 和 URL 的区别

URI包括URL和URN两个类别&#xff0c;URL是URI的子集&#xff0c;所以URL一定是URI&#xff0c;而URI不一定是URL URI Universal Resource Identifier 统一资源标志符&#xff0c;用来标识抽象或物理资源的一个紧凑字符串。 通过使用位置&#xff0c;名称或两者来标识Interne…

超好用!在线即可制作电子产品图册

​电子产品图册是展示产品特点、功能和外观的重要方式之一。通过图册&#xff0c;可以让客户更好地了解产品&#xff0c;增强信任感&#xff0c;从而促进销售。同时&#xff0c;对于企业来说&#xff0c;制作精美的电子产品图册也是展示企业文化和品牌形象的重要手段之一。 一、…

Matter学习笔记(2)——数据模型和设备类型

一、设备数据模型 Matter 中的设备具有明确定义的 数据模型(DM)&#xff0c;它是设备功能的分层建模。使用 属性(Attribute)、命令(Command) 和 事件(Event) 的概念描述 Matter 节点支持的远程操作&#xff0c;并分组为称为集群的逻辑块。Matter 应用集群规范中包含的集群具有…

提升绘图效率不再难,看看这8款AI流程图软件,一键快速生成流程图!

流程图是表示流程、系统和思想的重要视觉辅助工具。在当今数字时代&#xff0c;AI技术的出现已经彻底改变了制作流程图的方式。 在本文中&#xff0c;我们将与各位分享8款好用的AI流程图软件&#xff0c;借助每款软件内置的AI能力&#xff0c;可以快速绘制出一份完整的流程图&…

Java修仙传之神奇的ES2(巧妙的查询及结果处理篇)

SDL语句查询 查询的基本语法 GET /indexName/_search {"query": {"查询类型": {"查询条件": "条件值"}} } 根据文档id查询 #查询文档 GET hotel/_doc/36934 查询所有 会弹出该索引库下所有文档// 查询所有 GET /indexName/_searc…

乐园要吸引儿童还是家长?万达宝贝王2000万会员的求精之路

2023年6月&#xff0c;万达宝贝王正式迈入“400店时代”。 万达宝贝王在全国200多座城市&#xff0c;以游乐设施、主题活动、成长课程服务10亿多用户&#xff0c;拥有2000多万名会员&#xff0c;是真正的国内儿童乐园领跑者。 当流量时代变成“留量”时代&#xff0c;用户增长…

利用RoboBrowser库和爬虫代理实现微博视频的爬取

技术概述 微博是一个社交媒体平台&#xff0c;用户可以在上面发布和分享各种内容&#xff0c;包括文字、图片、音频和视频。微博视频是微博上的一种重要的内容形式&#xff0c;有时我们可能想要下载微博视频到本地&#xff0c;以便于观看或分析。但是&#xff0c;微博视频并没…