微信小程序开发-基础知识

444 阅读12分钟

[TOC]

自用备忘,待补全

基础

与浏览器开发的区别

  • js引擎与渲染引擎不互斥
  • 不包含dom bom 相关的api

语法

WXML

  • 数据绑定 <view> {{message}} </view>

  • 列表渲染 <view wx:for="{{array}}"> {{item}} </view>

  • 条件渲染

    <view wx:if="{{view == 'WEBVIEW'}}"> WEBVIEW </view>
    <view wx:elif="{{view == 'APP'}}"> APP </view>
    <view wx:else="{{view == 'MINA'}}"> MINA </view>
    
  • 模版

    <template name="staffName">
      <view>
        FirstName: {{firstName}}, LastName: {{lastName}}
      </view>
    </template>
    
    <template is="staffName" data="{{...staffA}}"></template>
    <template is="staffName" data="{{...staffB}}"></template>
    <template is="staffName" data="{{...staffC}}"></template>
    

WXSS

  • 单位rpx,默认规定屏幕宽度为750rpx
  • 外部样式导入,@import
  • 行内样式<view style="color:{{color}};" />.
  • 支持的选择器 id选择器 类选择器 元素选择器 ::before ::after
  • 动画,可以使用CSS 渐变CSS 动画
  • 使用js创建动画,this.animate(selector, keyframes, duration, callback),清除this.clearAnimation(selector, options, callback)
  • 基于滚动驱动的动画,this.animate(selector, keyframes, duration, ScrollTimeline)

WXS

  • ios渲染性能高,andriod渲染性能与js基本一致
  • 在wxml中书写js,<wxs module="wxs" src="./test.wxs"></wxs>

生命周期

页面生命周期

  • onLoad 页面创建后执行
  • onReady 页面渲染后执行
  • onUnload 页面卸载之前执行
  • onShow 页面出现在前台执行
  • onHide 页面从前台变为后台时执行
  • onPullDownRefresh 触发下拉刷新时执行
  • onReachBottom 触底时执行
  • onPageScroll 页面滚动时执行
  • onResize 页面大小变化时执行
  • onTabItem tab点击时执行
  • onShareAppMessage 页面被用户分享时执行
  • ...

全局生命周期

  • onLaunch // 小程序加载后触发

Js线程和渲染线程时如何协作的?

  1. js线程created 渲染线程init
  2. Js 线程依次触发 onLoad onShow,等待渲染线程的notify通知
  3. Js 线程收到渲染线程的notify通知后,向渲染引擎发送初始化数据
  4. 渲染线程接收到初始化数据,开始执行第一次渲染,渲染完成后,通知Js线程
  5. Js 线程收到渲染完成的消息,触发onReady事件
  6. 当数据更新时,Js 线程通知渲染线程进行渲染
  7. 当页面被隐藏到后台时,触发onHide事件
  8. 当页面从后台取消隐藏展示在前台时,触发onShow事件
  9. 当关闭或销毁该页面时,触发onUnload事件

路由

页面栈

  • getCurrentPages() 获取当前页面栈
  • navigateTo 新页面入栈
  • navigateBack 当前页面出栈
  • redirectTo 当前页面出栈,新页面入栈
  • switchTab 页面全部出栈,只剩下新的tab页面
  • reLaunch 页面全部出栈,只剩下新的页面

注意点

  • navigateTo 和 redirectTo 只能在非tabBar页面之间跳转
  • reLaunch 可以打开任何页面
  • switchTab 只能打开tabBar页面
  • 通过页面的onLoad中获取到路由的参数

事件

  • 事件绑定bindtap,bind:tap

  • 冒泡,bind方法默认支持冒泡,通过catch绑定可以阻止事件冒泡

  • 捕获,capture-bind,capture-catch

  • 互斥,mut-bind在冒泡/捕获过程中只触发一次,与父级/子组件上的mut-bind方法互斥

  • 动态绑定

    <view bindtap="{{ handlerName }}">
        Click here!
    </view>
    // handlerName 通过this.data.handlerName进行获取,必须是一个字符串,指定事件处理函数名
    

事件源对象

  • CustomEvent TouchEvent 都继承自BaseEvent
  • Target 事件触发的源对象,currentTarget 事件绑定的组件,常见于事件委托
  • target,currentTarget都可以通过dataset获取对应组件上的自定义属性
  • detail自定义事件所携带的数据
  • mark 不同于dataset,能够获取到经过冒泡/捕获的一系列组件的自定义mark的值

数据

双向绑定

  • <input value="{{value}}" />  <input model:value="{{value}}" />
    
  • 自定义组件的双向绑定传递

    // custom-component.js
    Component({
      properties: {
        myValue: String
      }
    })
    
    <!-- custom-component.wxml -->
    <input model:value="{{myValue}}" />
    

    使用

    <custom-component model:my-value="{{pageValue}}" />
    

数据存储

获取节点信息

  • const query = wx.createSelectorQuery()
    
  • 节点布局相交状态

    wx.createIntersectionObserver().relativeToViewport().observe('.target-class', (res) => {
          res.id // 目标节点 id
          res.dataset // 目标节点 dataset
          res.intersectionRatio // 相交区域占目标节点的布局区域的比例
          res.intersectionRect // 相交区域
          res.intersectionRect.left // 相交区域的左边界坐标
          res.intersectionRect.top // 相交区域的上边界坐标
          res.intersectionRect.width // 相交区域的宽度
          res.intersectionRect.height // 相交区域的高度
        })
    

发起网络请求

  • 包括普通 HTTPS 请求(wx.request)、上传文件(wx.uploadFile)、下载文件(wx.downloadFile) 和 WebSocket 通信(wx.connectSocket)。从 2.7.0 开始,提供了 UDP 通信(wx.createUDPSocket)
  • 超时时间可以在 app.jsongame.json 中通过 networktimeout 配置。默认60秒。
  • 网络请求的 referer header 不可设置。
  • wx.requestwx.uploadFilewx.downloadFile 的最大并发限制是 10 个;
  • wx.connectSocket 的最大并发限制是 5 个。
  • 小程序进入后台运行后,如果 5s 内网络请求没有结束,会回调错误信息 fail interrupted;在回到前台之前,网络请求接口调用都会无法调用。
  • 建议服务器返回值使用 UTF-8 编码。对于非 UTF-8 编码,小程序会尝试进行转换,但是会有转换失败的可能。
  • 小程序会自动对 BOM 头进行过滤(只过滤一个BOM头)。
  • 只要成功接收到服务器返回,无论 statusCode 是多少,都会进入 success 回调。请开发者根据业务逻辑对返回值进行判断。

特性

模块化

  • 通过module.exports和require进行引入导出操作

作用域

  • 每一个文件都是一个单独的作用域
  • 可以在app.js中定义全局变量,并通过getApp().xx方法获取

API

  • 事件监听API以on开头
  • 以sync结尾的api为同步api
  • 大部分异步api接收一个对象作为参数,包含success,fail,complete,以及接口定义的其他参数。不传递时,小程序2.10.2版本起默认返回一个promise对象
  • 回调函数的参数,errorMsg(成功时返回ok),errorCode(成功时返回0),以及接口返回的其他数据
  • wx.cloud.callFunction()调用云函数

开发

开发文件

  • 单独配置文件 page.json,全剧配置文件app.json,工具配置文件project.config.json,sitemap.json用于配置页面能否被索引
  • .wxml 用于书写html
  • .wxss 用于书写css
  • .wxs 不同与javascript,属于小程序的脚本语言,性能高要求的项目优先使用
  • .js 用于渲染.wxml

内置API

  • 获取地理位置 wx.getLocation
  • 扫一扫 wx.scanCode

数据方法共享

  • 页面可以引用 behaviors 。 behaviors 可以用来让多个页面有相同的数据字段和方法

自定义TabBar

  • app.json 中的 tabBar 项指定 custom 字段,同时其余 tabBar 相关配置也补充完整。
  • 所有 tab 页的 json 里需声明 usingComponents 项,也可以在 app.json 全局开启。
  • 添加tabBar代码文件。代码根目录下添加入口文件:custom-tab-bar/index.js(.json.wxml.wxss)

自定义组件

组件插槽

  • 多个slot通过options配置multipleSlots: true 开启,slot 定义 name='a',父组件使用传递slot='a'

组件样式

  • 样式约束,使用类选择器,不能使用后代选择器

  • 样式隔离

    • options中开启styleIsolation: 'isolated'/ 'apply-shared'
    • 2.10.1以上,可以在自定义组件的json文件中配置styleIsolation: 'isolated'
    • 2.2.3以上,在 Componentoptions 中设置 addGlobalClass: true,表示页面的wxss样式可以影响到自定义组件
  • 外部样式传入, 在 Component 中用 externalClasses 定义段定义若干个外部样式类

    Component({
      externalClasses: ['my-class']
    })
    
  • 配置options中的virtualHost: true,自定义组件并不希望这个节点本身可以设置样式、响应 flex 布局等,而是希望自定义组件内部的第一层节点能够响应 flex 布局或者样式由自定义组件本身完全决定

component构造器

  • 可以定义组件
  • 可以定义页面,需要配置页面page.json的"usingComponents": {}。properties用于接收页面的路由参数,methods用于定义页面的生命周期方法
  • 好处,可以使用behaviors来提取多个页面的公共代码

父子组件通信

  • 父组件访问子组件,this.selectComponent(selector) 方法获取子组件实例对象。若需要自定义selectComponent的返回数据,可使用内置 behavior: wx://component-export配合自定义组件中的 export 定义段将用于指定组件被 selectComponent 调用时的返回值
  • 子组件触发父组件绑定的事件,this.triggerEvent('myevent', myEventDetail, myEventOption)

生命周期

  • created。通常情况下,这个生命周期只应该用于给组件 this 添加一些自定义属性字段。此时还不能调用 setData
  • attached。在组件完全初始化完毕、进入页面节点树后触发。绝大多数初始化工作可以在这个时机进行
  • detached。组件离开页面节点树后或者退出一个页面且组件还在页面节点树中触发
  • 定义方式
    • 定义在第一级参数重
    • 定义在lifetimes中
  • 组件所在页面的生命周期,在 pageLifetimes 定义段中定义

behaviors

  • 可以包含一组属性、数据、生命周期函数和方法
  • 组件引用它时,它的属性、数据和方法会被合并到组件中,生命周期函数也会在对应时机被调用
  • 组件可以引用多个behaviors
  • 自定义组件可以通过引用内置的 behavior 来获得内置组件的一些行为

组件间的关系

  • 定义relations: {path, {type, linked, linkChanged, unlinked, target}}字段。

监听器

  • observes: {propName: function(){}}。用于监听data中属性的变化

纯数据字段

  • 不参与渲染的数据字段,可通过options 定义段中指定 pureDataPattern 为一个正则表达式,字段名符合这个正则表达式的字段将成为纯数据字段
  • 可以通过observes监听纯数据字段的变化来渲染界面

抽象节点

  • 动态的决定自定义组件内部引用的节点。需要在componentGenerics中声明:

    <!-- component.wxml -->
    <view wx:for="{{labels}}">
      <label>
        <xxx></xxx>
        {{item}}
      </label>
    </view>
    
    // component.json
    {
      "componentGenerics": {
        "xxx": true
      }
    }
    

    使用<selectable-group generic:xxx="custom-radio" />

  • 设置默认节点

    {
      "componentGenerics": {
        "selectable": {
          "default": "path/to/default/component"
        }
      }
    }
    
  • 节点的 generic 引用 generic:xxx="yyy" 中,值 yyy 只能是静态值,不能包含数据绑定。因而抽象节点特性并不适用于动态决定节点名的场景。

自定义组件拓展

  • Behavior() 构造器提供了新的定义段 definitionFilter ,用于支持自定义组件扩展
  • definitionFilter 是一个函数,在被调用时会注入两个参数,第一个参数是使用该 behavior 的 component/behavior 的定义对象,第二个参数是该 behavior 所使用的 behavior 的 definitionFilter 函数列表

插件使用

  • app.json 中声明需要使用的插件
  • 如果插件只在一个分包内用到,可以将插件仅放在这个分包内。如果基础库版本低于 2.9.0 ,不能从分包外的页面直接跳入分包内的插件页面,需要先跳入分包内的非插件页面、再跳入同一分包内的插件页面
  • 使用插件提供的自定义组件,和 使用普通自定义组件 的方式相仿。在 json 文件定义需要引入的自定义组件时,使用 plugin:// 协议指明插件的引用名和自定义组件名
  • 需要跳转到插件页面时,url 使用 plugin:// 前缀,形如 plugin://PLUGIN_NAME/PLUGIN_PAGE
  • 使用插件的 js 接口时,可以使用 requirePlugin 方法。

操作本地文件

  • 通过 wx.getFileSystemManager() 可以获取到全局唯一的文件系统管理器,所有文件系统的管理操作通过 FileSystemManager 来调用
  • 本地临时文件(如tempFilePaths),随时会被回收,不计大小。本地缓存文件/本地用户文件,不能/可以自定义目录,两者相加最多可存储200M

代码分包

  • 整个小程序所有分包大小不超过 20M
  • 单个分包/主包大小不能超过 2M
  • 通过在app.jsonsubpackages来定义分包。对应的分包配置项中定义independent字段声明对应分包为独立分包
    • 独立分包中暂时不支持使用插件。
    • App 只能在主包内定义,独立分包中不能定义 App,会造成无法预期的行为;
    • 独立分包中不能依赖主包和其他分包中的内容
  • 为了规避在分包中获取主包的getApp时,获取不到情况(分包加载主包可能未加载)。可以设置getApp({allowDefault: true}),返回一个默认实现
  • app.json 增加 preloadRule 配置来控制分包的预加载

适配

  • 手机上启用屏幕旋转,app.json/page.json配置 "pageOrientation": "auto"

  • ipad配置屏幕旋转,app.json "resizable": true

  • 监听屏幕旋转,页面上onResize,自定义组件中pageLifetimes:{resize},wx.onWindowResize

  • 媒体查询

    .my-class {
      width: 40px;
    }
    
    @media (min-width: 480px) {
      /* 仅在 480px 或更宽的屏幕上生效的样式规则 */
      .my-class {
        width: 200px;
      }
    }
    

生产

场景值

用户体验优化

  • 使用初始渲染缓存,页面的page.json中配置"initialRenderingCache": "static",全局配置,app.json中的window配置,"initialRenderingCache": "static"
  • 初始渲染缓存中添加动态内容,"initialRenderingCache": "dynamic",同时在页面中调用this.setInitialRenderingCache(dynamicData)
  • 禁用初始渲染缓存的方式,this.setInitialRenderingCache(null)

小程序启动

  • 冷启动(重新加载启动)和热启动(从后台进入前台)
  • 小程序销毁的原因,用户长时间为唤醒小程序,小程序系统占用资源过高(通过wx.onMemoryWarning)
  • 启动策略
    • A场景,冷启动,遵循重启策略,可能打开首页或上次浏览的页面。热启动,返回之前浏览的页面
    • B场景,每次打开都reLaunch到指定页面
  • 在页面对应的 json 文件中(也可以全局配置在 app.json 的 window 段中),指定 restartStrategy 配置项可以改变这个默认的行为
  • 可以在退出时保存页面上的状态,通过页面的onSaveExitState进行保存

小程序更新机制

  • 无法时时更新,最晚在发后后24小时内下发新版本信息到用户
  • 在冷启动时,可以通过 wx.getUpdateManager API 进行处理

其他

Worker

  • Worker 与主线程之间的数据传输,双方使用 Worker.postMessage() 来发送数据,Worker.onMessage() 来接收数据,传输的数据并不是直接共享,而是被复制的。