WEB端基础-小程序原生摘要1-简述

242 阅读13分钟

前言

小程序开发已成为Web端开发的重要组成部分,鉴于目前的业务需求,我们需要满足小程序的日常开发,此文用于记录小程序的基础开发摘要。

概述

小程序提供了一个简单、高效的应用开发框架和丰富的组件及API,帮助开发者在微信中开发具有原生 APP 体验的服务。小程序的底层原理应该是借鉴了vue的设计理念,采用mvvm模式的响应式编程。

差异性

小程序的主要开发语言是 JavaScript,网页开发渲染线程和脚本线程在小程序中是分开的,分别运行在不同的线程中。小程序的逻辑层运行在 JSCore 中,并没有一个完整浏览器对象,因而缺少相关的DOM API和BOM API。这一区别导致了前端开发非常熟悉的一些库,例如 jQuery、 Zepto 等,在小程序中是无法运行的。同时 JSCore 的环境同 NodeJS 环境也是不尽相同,所以一些 NPM 的包在小程序中也是无法运行的。
小程序开发过程中需要面对的是三大操作系统 iOS 、Android、harmony 的微信客户端,以及用于辅助开发的小程序开发者工具,运行环境如下:

运行环境逻辑层渲染层
iOSJavaScriptCoreWKWebView
安卓V8chromium定制内核
小程序开发者工具NWJSChrome WebView

指南

代码构成

项目中会生成JSON配置文件、WXML模版文件、WXSS样式文件、JS脚本逻辑文件,以此来划分页面配置、UI模版、样式与业务逻辑。

  • JSON配置:用于记录配置的静态文件:
    • app.json:小程序的所有页面路径、界面表现、网络超时时间、底部 tab 等;
    • project.config.json: 工具个性化配,例如界面颜色、编译配置、代码上传时自动压缩,云端存储,自动恢复;
    • page.json:页面的个性化配置内容;
  • WXML模版:与.html相似的xml结构,使用微信封装的各种控件,例如:view、button、image、text等。
  • WXSS样式:具备css的大部分特性,并做了扩充和修改。新增rpx尺寸样式以适配不同的设备屏幕。提供全局样式app.wxss与页面样式page.wxss。
  • JS逻辑交互:相应页面的各种事件、处理数据及逻辑显示,可以调用WX的各种封装API,例如:登录、本地存储、微信支付。

宿主环境

微信客户端即为宿主。

  • 渲染层与逻辑层:页面的渲染由WebView进行渲染,多个页面则有多个WebView线程。逻辑层采用JSCore线程运行。线程通信都经由客户端中转,逻辑层的网络请求也Native转发,
  • 程序与界面:客户打开小程序前,会把整个小程序的代码包下载到本地,注意这里只是主程序的相关代码。APP与页面都有自己的生命周期回调,请注意使用方式。

版本管理

  • 不同版本的区别

    • 开发版本:只保留每人最新的一份上传代码。可删除,不影响其他版本。
    • 体验版本:选择某一开发版本作为体验版。
    • 审核中版本:提交审核,且只能有一个份代码处于审核,重新提交可覆盖。
    • 线上版本:线上用户使用的最新版。
  • 发布上线:经过 预览-> 上传代码 -> 提交审核 -> 发布等步骤。

框架

逻辑层
  • behaviors:页面可以引用 behaviors ,用来让多个页面有相同的数据字段和方法。类似vue的mixin。

  • Component:主要用于复杂页面的拆分,有点像Flutter中闲鱼的拆分结构。

  • 生命周期:微信的生命周期有点不同,需要双线程的通信处理。 图片

  • 路由:路由方式包括初始化、打开新的页面、重定向、页面返回、tab切换、重加载。Tab 切换遵从懒加载、root操作方式。

  • 模块化:抽离共有js文件,通过 module.exports或者 exports 才能对外暴露接口。在需要使用这些模块的文件中,使用 require 将公共代码引入。注意文件作用域,如需全局变量,可使用APP()存储。

  • API:小程序开发框架提供丰富的微信原生 API,可以方便的调起微信提供的能力,如获取用户信息,本地存储,支付功能等。

    • 监听API:以 on 开头的 API 用来监听某个事件是否触发,如 wx.onSocketOpen

    • 同步API:以 Sync 结尾的 API 都是同步 API,如 wx.setStorageSync

    • 异步API: 大多数 API 都是异步 API,如 wx.request

    • Promise: 基础库 2.10.2 版本起,异步 API 支持 callback & promise 两种调用方式。这与vuePromise 的应用极为相似。

视觉层View

框架的视图层由 WXMLWXSS 编写,由组件来进行展示,将逻辑层的数据反映成视图,同时将视图层的事件发送给逻辑层。

  • WXML : 一套类似VUE2.0的一套标签语言,包括数据绑定列表渲染条件渲染模板引用等内容。

  • WXSS:css基础之上的一套样式语言。内容包括尺寸单位的适配规则、其他样式的导入、内联样式、选择器。

  • WXS: 小程序的自己的脚本语言,类似 JS,内联在 WXML 中。为 WXML 提供丰富模板的数据预处理能力。本身不能处理自定义组件事件,只能响应内置组件的事件。

  • 点击事件:事件是视图层到逻辑层的通讯方式。携带如 id, dataset, touches等信息。这诟病满满啊,传递要素过多,灵活性相比vue差太多。

    • 事件分类:冒泡与非冒泡,也就是透传的概念。

    • 普通事件绑定:bind:tap 的属性为字符串,可以是可变数据。

    • 阻止事件冒泡:catch 绑定会阻止向上冒泡。

    • 互斥绑定:mut-bind 互斥是指冒泡过程中的mut-bind方法只执行一次。

    • 事件捕获:触摸类事件支持捕获阶段,捕获阶段位于冒泡阶段之前,且在捕获阶段中,事件到达节点的顺序与冒泡阶段恰好相反。采用capture-bindcapture-catch关键字,后者将中断捕获阶段和取消冒泡阶段。

    • 事件对象:事件函数触发会接收到一个事件对象

      • type:事件类型,如tap等;
      • timeStamp:事件生成时的时间戳,毫秒级;
      • target:触发组件的属性值集合;
        • id:组件id
        • dataSet:data-开头的自定义属性组成的集合,编写用-,使用转驼峰写法;
      • currentTarget:响应组件的属性集合(冒泡会改变,同target);
      • mark:事件标记数据;
        • 2.7.1以上使用;
        • 冒泡路径上的所有mark都会被合并;
        • 同名时,子覆盖父;
        • 不会转换字符标记;
        • 自定义组件中只包含组件内的mark;
      • detail:额外的信息;
      • touches:触摸事件,当前停留在屏幕中的触摸点信息的数组;
      • changedTouches:触摸事件,当前变化的触摸点信息的数组;
    • 响应事件:为降低逻辑层与视图层的频繁交互,wx提倡使用 wxs 在视图层完成数据及UI处理。

    • 双向绑定:同vuemodel:value简单绑定,数据处理后更新需要this.setData({ value: 'leaf' })的写法。组件需要借助Component中的properties属性。

    • 基础组件:框架为开发者提供了一系列基础组件.

    • 节点信息:节点信息查询API可以用于获取节点属性、样式、在界面上的位置等;节点布局相交状态API可用于监听两个或多个组件节点在布局位置上的相交状态。

    • 显示区域:改变显示区域的尺寸的方法有支持屏幕旋转、启动大屏模式。

    • 分栏模式:小程序提供在较大屏幕的分栏显示。

    • 动画:在小程序中,通常可以使用 CSS 渐变 和 CSS 动画 来创建简易的界面动画。

    • 初始渲染:

      • 逻辑层与视图层分别初始化。
      • 可以启动初始化缓存,提前渲染页面。
      • 初始化渲染只能使用内置组件。
      • 可动态配置初始化渲染。

运行时

运行环境

微信小程序运行在多种平台上,不同运行环境下,脚本执行环境以及用于组件渲染的环境是不同的,性能表现也存在差异;平台间存在差异性,建议开发完成在各端检查。

JavaScript 支持
  • 不支持动态执行JS代码,不支持创建函数;
  • 内置core-js,提高ECMAScript标准兼容性,但无法抹平,如async/await时,需要借助 代码转换工具 来支持这些语法。
  • 避免使用Proxy 对象。
  • Promise 时序在iOS环境下存在差异。
运行机制
  • 生命周期:小程序从启动到最终被销毁,会经历很多不同的状态。
    图片
  • 启动:分为冷启动与热启动。
  • 前后台:展示给用户为前台,退出为后台。
  • 挂起:后台后5秒停止JS运行,常驻功能会持续运行,如音乐、地理位置。
  • 销毁:长时间未使用嚯资源紧张会销毁小程序。
  • 冷启动与热启动:有自己的一套规则和配置。
  • 退出状态:销毁前会调用onSaveExitState用于保存一些数据状态。
更新机制

微信客户端会有若干个时机去检查本地缓存的小程序有没有新版本,并进行小程序的代码包更新。

  • 启动时同步更新:在以下情况下,小程序启动时会同步更新代码包。同步更新会阻塞小程序的启动流程,影响小程序的启动耗时。

    • 定期检查:微信运行时,会定期检查最近使用的小程序是否有更新。如果有更新,下次小程序启动时会同步进行更新,更新到最新版本后再打开小程序,尽可能保证用户能够尽快使用小程序的最新版本。

    • 长时间未使用:为保障小程序版本的实时性,会强制同步检查版本更新,更新到最新版本后再打开小程序。

    • 弱网、下载失败仍会启动旧的版本。

  • 启动时异步更新:启动前未发现更新,小程序每次冷启动时,都会异步检查是否有更新版本。如果发现有新版本,将会异步下载新版本的代码包。但当次启动仍会使用客户端本地的旧版本代码,即新版本的小程序需要等下一次冷启动才会使用。

    • 开发者可以使用getUpdateManagerAPI手动触发,重启小程序。
  • 小程序后台设置:

    • 优先使用本地设置:无需强制用户同步更新到最新版本,优先使用本地版本,异步下载最新代码包。
    • 最低可用版本:设置后同步检查本地低于该版本,则无法打开,并尝试下载最新版本,更新后会重新小程序。

自定义组件

介绍

页面内的功能模块抽象成自定义组件

  • 将组件内.json中声明 componenttrue
  • 组件中.wxss中不应使用ID选择器、属性选择器和标签名选择器。
  • 组件中.js中声明Component构造器。
  • 使用组件在.json中的usingComponents设定。
  • 创建组件后,如出现找不到.wxml,请清除缓存。

模版与样式

  • 组件模版
    • 组件模板的写法与页面模板相同。
    • 组件模板中可以提供<slot> 节点,用于承载引用位置的子节点。
  • 数据绑定
    • 可以使用数据绑定,动态传递。
    • 组件内的wxss只对组件负责.
    • 样式隔离:
      • styleIsolation可指定样式隔离逻辑。
      • wxss要避免使用标签名选择器。
    • 外部样式使用 externalClasses
    • 样式中添加~用来引用页面样式或父组件样式。
    • 使用virtualHost来构建虚拟节点,拒绝父类的设定。

Component 构造器

  • 构造器时可以指定组件的属性、数据、方法等。
  • 可以用来构造页面,并使用behaviors 来提取所有页面中公用的代码段。

通信与事件

  • 组件通讯方式
    • WXML 数据绑定:父控件向子控件指定数据。
    • 事件:子控件向父控件传递任意值。
    • 父控件通过this.selectComponent方法获取子组件实例对象,访问数据、方法。
  • 监听事件:可以监听自定组件的触发事件,如bindmyeventbind:myevent
  • 触发事件:使用triggerEvent指定事件名、detail对象和事件选项。
  • 获取组件实例:通过selector,如:this.selectComponent(".my-component")

生命周期

组件的生命周包括以下回调,另外所在页面的生命周期强相关,在pageLifetimes定义。

  • created:创建时执行。
  • attached:进入页面节点。
  • ready:视图层布局完成。
  • moved:组件被移动到另外一个节点。
  • detached:从页面节点移除。
  • error:组件执行出错抛出。

behaviors

类似vuemixins的特性,用于抽离共同属性、数据和方法。

  • 使用需require引用,组件behaviors添加引用方法名。
  • 覆盖组合规则:
    1. 属性和方法:主覆盖引,后覆盖前。
    2. 数据字段:同类合并,主覆盖引,后覆盖前。
    3. 生命周期与observer调用:按主顺序,先引后主,先前后后。
  • 内置behavior:自定义组件可以通过引用内置的 behavior 来获得内置组件的一些行为。

组件间关系

  • 定义组件关系:可以添加relations字段用关系组件的调用。
  • 关联一类组件:使用Behavior作为子控件共有内容,在relations使用Behavior代替组件路径作为关联节点。

数据监听器

数据监听器可以用于监听和响应任何属性和数据字段的变化,类似vue中的计算属性。

  • 使用observers描述监听属性与处理方法。
  observers: {
    'numberA, numberB': function(numberA, numberB) {
      // 在 numberA 或者 numberB 被设置时,执行这个函数
      this.setData({
        sum: numberA + numberB
      })
    }
  }
  • 可以监听子数据段,还可以使用**通配符批量匹配。

纯数据字段

纯数据字段是一些不用于界面渲染的 data 字段,可以用于提升页面更新性能。

  • 使用pureDataPattern匹配纯数据字段。
  • 属性也可以创建纯数据字段,但不可用于WXML及监听属不执行。
  • 使用数据监听器可以监听纯数据字段。

抽象节点

支持建立抽象的节点,由调用位置确定具体的插入组件的具体类型,可以提供默认组件类型。

自定义组件扩展

行文习惯

  • 内部方法建议以下划线开头。

常用枚举集合

文献: