小程序技术分享大纲

396 阅读5分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第1天,点击查看活动详情 # 分享

什么是小程序

小程序是一种不需要下载安装即可使用的应用,它实现了应用“触手可及”的梦想,用户扫一扫或搜一下即可打开应用。 小程序上线以来,一直被称为便携式的 APP,关于两者之间的区别,无外乎是小程序相对轻便、开发成本低、开发周期短,收效快。


宿主环境

微信小程序的宿主环境为微信客户端,它是依赖于微信客户端上运行的,并且跟小程序 基础库 版本有重大关联关系


执行环境

  • 网页开发,渲染线程和脚本是互斥的,这也是为什么长时间的脚本运行可能会导致页面失去响应的原因,本质就是我们常说的JS是单线程的。

  • 小程序,视图层和逻辑层是分开的,双线程同时运行,视图层的界面使用 webView 进行渲染,逻辑层运行在JScore中。

  • 网页开发,主要面对各厂商的浏览器,在移动端还需要面对 Safari、Chrome 以及 iOS、Android 系统中的各式 WebView。

  • 小程序,主要面对两大操作系统IOS和Android的微信客户端,还有开发工具、PC端(window)、Mac。开发时候需要注意的是微信客户端的版本号和小程序API 支持的基础库版本号。微信小程序运行在多种平台上:iOS(iPhone/iPad)微信客户端、Android 微信客户端、PC 微信客户端、Mac 微信客户端和用于调试的微信开发者工具


小程序整体架构

通过上面的内容,大致了解小程序诞生的情况和所处的环境了,下面我们来聊聊小程序的整体设计架构情况。

整个小程序系统架构分成两个部分:视图层(WebView) 和 逻辑层(App Service),这两个部分分别由两个独立线程管理。

  • 视图层:也称为渲染层,渲染层用来渲染页面结构,主要 WebView 进行渲染,一个小程序可以存在多个界面,所以渲染层可能存在多个 WebView 线程。
  • 逻辑层:逻辑层采用 JScore 线程运行 JS 脚本。逻辑层主要用来逻辑处理、数据请求、接口调用等

视图层和逻辑层之间的沟通则需要借助 系统层(WeixinJsBridage) 进行通信,逻辑层把数据变化通知到视图层,触发视图层页面更新,视图层把触发的事件通知到逻辑层进行业务逻辑处理。


文件目录

  • components -组件
    • f-toast
  • miniprogram_npm
    • 微信开发者工具构建npm后建立的文件夹
  • pages -写页面的地方,在app.json里定义每个页面的页面路径,一个页面由四个文件组成
    • home
      • home.js -页面逻辑
      • home.wxml -页面结构
      • home.wxss -页面配置
      • home.json -页面样式表(独立的)
  • static -静态资源文件
    • icons
    • imgs
  • utils -封装的一些方法
    • server - 接口
      • Authenticate.js - /api/Authenticate/LogOut
    • request.js -请求方法
    • utils.js -封装改日期格子的方法
  • app.js 小程序逻辑(全局)
  • app.json 小程序的全局配置,包括了小程序的所有页面路径、界面表现、网络超时时间、底部 tab 等
  • app.wxss 小程序的公共样式
  • 官方文档

生命周期

  • 小程序生命周期

              // app.js
              App({
    
                  onLaunch (options) {
                      // 小程序初始化完成时触发,全局只触发一次。
                  },
                  onShow (options) {
                      // 小程序启动,或从后台进入前台显示时触发。
                  },
                  onHide () {
                      // 小程序从前台进入后台时触发。
                  },
                  onError (msg) {
                      console.log(msg)
                      // 小程序发生脚本错误或 API 调用报错时触发。也可以使用 wx.onError 绑定监听。
                  },
                  globalData: 'I am global data'
                  // 整个小程序只有一个 App 实例,是全部页面共享的。开发者可以通过 getApp 方法获取到全局唯一的 App 实例,获取 App 上的数据或调用开发者注册在 App 上的函数。
    
              })
    
              // page.js
              const app = getApp();
              console.log(app.globalData) //  I am global data
    
  • 页面生命周期


自定义组件

开发者可以将页面内的功能模块抽象成自定义组件,以便在不同的页面中重复使用;也可以将复杂的页面拆分成多个低耦合的模块,有助于代码维护。

父与子之间通信

  • 父传子

  • 子传父

          <!--父级html文件-->
          <feis-title titleText="{{title}}" bindmyevent="onMyEvent"></feis-title>
    
          <!--父级js文件-->
          onMyEvent:function(e){
              console.log(e.detail.data)
          }
    
          <!--子级html文件-->  
          <view bindtap="getData">
    
          <!--子级js文件-->
          properties: {
              titleText:{
                  type:String,
                  value:'其他'
              }
          methods:{
              getData(){
                  this.triggerEvent('myevent', data)
              }
          }
    

wxml

WXML(WeiXin Markup Language)是框架设计的一套标签语言

  • 数据绑定

    • 插值表达式

            <!--wxml-->
            <view> {{message}} </view>
      
            // page.js
            Page({
                data: {
                    message: 'Hello!'
                }
            })
      
      • 单向绑定

        • 在 WXML 中,普通的属性的绑定是单向的

            <!--wxml-->
            <input value="{{ abc }}" bindtap="getData" />
          
            // page.js
                getData:function(e){
                    let data = e.detail.value
                    this.dataset({ abc:data })
                }
          
      • 双向绑定

           <!--wxml-->
           <input model:value="{{ abc }}" /> 
        
        • 这样,如果输入框的值被改变了, this.data.value 也会同时改变。同时, WXML 中所有绑定了 value 的位置也会被一同更新, 数据监听器 也会被正常触发。

        • 用于双向绑定的表达式有如下限制:

          • 只能是一个单一字段的绑定,如

          <input model:value="值为 {{value}}" />

          <input model:value="{{ a + b }}" />

          • 目前,尚不能 data 路径,如

          <input model:value="{{ a.b }}" />

        • 标签属性值为true,可以省略=“{{ true }}”,如

          <input isShow="{{ true }}" value="{{ value }}" />

          <input isShow value="{{ value }}" />

  • 条件渲染

    • wx:if和hidden

      • wx:if类似于v-if,都是条件为真时显示标签。也是通过销毁创建dom元素的方法来进行dom元素的隐藏和显示

        <view wx:if="{{ true }}"> 1 </view>

        <view wx:if="{{length > 5}}"> 1 </view>

          <!--wxml-->
          <view wx:if="{{ isShow }}"> 1 </view>
          //page.js
          data:{
              isShow:ture
          }
        
      • 其中 wx:if wx:elif wx:else 和vue中的 v-if v-else-if v-else相对应,使用也是一样的

    • hidden类似v-show,不同点在于当条件为true时,hidden会隐藏标签,但是v-show是显示标签。但他们的显示隐藏都是通过css display样式来进行控制

      <view hidden="{{ true }}"></view> 隐藏

  • 列表渲染

    • wx:for
      • wx:for和vue里的v-for差别不是很多,大体的语法和渲染都和vue一致

      • 默认数组的当前项的下标变量名默认为 index,数组当前项的变量名默认为 item

              <view wx:for="{{array}}" wx:key="index" wx:for-index="index" wx:for-item="list">
                  {{index}}: {{item.message}}
              </view>
        
      • 关键字 wx:key="index"

      • 下标变量名 索引 wx:for-index="index"

      • 变量名 wx:for-item="list"


<block/> 并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性。