目录

一,框架简介

响应的数据绑定

二,视图层 View

WXML (html)

WXSS 样式

JS 逻辑交互

三,事件

什么是事件

事件的使用方式

四,逻辑层 APP service

1,生命周期 

 生命周期演示

页面路由

页面栈

路由方式

注意事项

3,模块化

模块化

文件作用域


一,框架简介

小程序开发框架的目标是通过尽可能简单、高效的方式让开发者可以在微信中开发具有原生 APP 体验的服务。

整个小程序框架系统分为两部分:逻辑层(App Service)和 视图层(View)。小程序提供了自己的视图层描述语言 WXML 和 WXSS,以及基于 JavaScript 的逻辑层框架,并在视图层与逻辑层间提供了数据传输和事件系统,让开发者能够专注于数据与逻辑。

响应的数据绑定

框架的核心是一个响应的数据绑定系统,可以让数据与视图非常简单地保持同步。当做数据修改的时候,只需要在逻辑层修改数据,视图层就会做相应的更新。

通过这个简单的例子来看:

在开发者工具中预览效果

android 自定义小程序容器 android 小程序框架_xml

新建一个页面 将上图中的代码分别放在不同的文件中进行编译即可

android 自定义小程序容器 android 小程序框架_android 自定义小程序容器_02

 test.wxml

<view class="hello"> Hello {{name}}! </view>
<button bindtap="changeName"> Click me! </button>

android 自定义小程序容器 android 小程序框架_ide_03

test.wxss

android 自定义小程序容器 android 小程序框架_android 自定义小程序容器_04

test.js

data: {
    name:'Weixin'
    
  },


 changeName: function(e) {
    // sent data change to view
    this.setData({
      name: 'MINA'
    })
  }

android 自定义小程序容器 android 小程序框架_xml_05

android 自定义小程序容器 android 小程序框架_ide_06

二,视图层 View

用以下一些简单的例子来看看 他们分别具有什么能力:

列表渲染

<!--wxml-->
<view wx:for="{{array}}"> {{item}} </view>
// page.js
Page({
  data: {
    array: [1, 2, 3, 4, 5]
  }
})

条件渲染

<!--wxml-->
<view wx:if="{{view == 'WEBVIEW'}}"> WEBVIEW </view>
<view wx:elif="{{view == 'APP'}}"> APP </view>
<view wx:else="{{view == 'MINA'}}"> MINA </view>
// page.js
Page({
  data: {
    view: 'MINA'
  }
})

模板

<!--wxml-->
<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>
// page.js
Page({
  data: {
    staffA: {firstName: 'Hulk', lastName: 'Hu'},
    staffB: {firstName: 'Shang', lastName: 'You'},
    staffC: {firstName: 'Gideon', lastName: 'Lin'}
  }
})

WXML (html)

WXML(WeiXin Markup Language)是框架设计的一套标签语言,结合基础组件事件系统,可以构建出页面的结构。

要完整了解 WXML 语法,请参考WXML 语法参考

将上述代码分别放入不同的文件进行编译演示

WXML

android 自定义小程序容器 android 小程序框架_小程序_07

 代码

<!--wxml-->
<view wx:for="{{array}}"> {{item}} </view>
<!--wxml-->
<view wx:if="{{view == 'WEBVIEW'}}"> WEBVIEW </view>
<view wx:elif="{{view == 'APP'}}"> APP </view>
<view wx:else="{{view == 'MINA'}}"> MINA </view>
<!--wxml-->
<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 样式

WXSS (WeiXin Style Sheets)是一套样式语言,用于描述 WXML 的组件样式。

WXSS 用来决定 WXML 的组件应该怎么显示。

为了适应广大的前端开发者,WXSS 具有 CSS 大部分特性。同时为了更适合开发微信小程序,WXSS 对 CSS 进行了扩充以及修改。

JS 逻辑交互

一个服务仅仅只有界面展示是不够的,还需要和用户做交互:响应用户的点击

、获取用户的位置等等。在小程序里边,我们就通过编写 JS 脚本文件来处理用户的操作。

android 自定义小程序容器 android 小程序框架_android 自定义小程序容器_08

 代码

/**
   * 页面的初始数据
   */
  data: {
    name:'Weixin',
    array: [1, 2, 3, 4, 5],
    view: 'APP',
    staffA: {firstName: 'Hulk', lastName: 'Hu'},
    staffB: {firstName: 'Shang', lastName: 'You'},
    staffC: {firstName: 'Gideon', lastName: 'Lin'}
  },

三,事件

什么是事件

  • 事件是视图层到逻辑层的通讯方式。
  • 事件可以将用户的行为反馈到逻辑层进行处理。
  • 事件可以绑定在组件上,当达到触发事件,就会执行逻辑层中对应的事件处理函数。
  • 事件对象可以携带额外信息,如 id, dataset, touches。

事件的使用方式

  • 在组件中绑定一个事件处理函数。

与上文中的点击切换了字体字体不同 而应该是如bindtap,当用户点击该组件的时候会在该页面对应的 Page 中找到相应的事件处理函数。

<view id="tapTest" data-hi="Weixin" bindtap="tapName"> Click me! </view>
  • 在相应的 Page 定义中写上相应的事件处理函数,参数是event。
Page({
  tapName: function(event) {
    console.log(event)
  }
})
  • 可以看到 log 出来的信息大致如下:
{
  "type":"tap",
  "timeStamp":895,
  "target": {
    "id": "tapTest",
    "dataset":  {
      "hi":"Weixin"
    }
  },
  "currentTarget":  {
    "id": "tapTest",
    "dataset": {
      "hi":"Weixin"
    }
  },
  "detail": {
    "x":53,
    "y":14
  },
  "touches":[{
    "identifier":0,
    "pageX":53,
    "pageY":14,
    "clientX":53,
    "clientY":14
  }],
  "changedTouches":[{
    "identifier":0,
    "pageX":53,
    "pageY":14,
    "clientX":53,
    "clientY":14
  }]
}

可以以此进行传递额外信息

四,逻辑层 APP service

1,生命周期 

生命周期 | 微信开放文档微信开发者平台文档

android 自定义小程序容器 android 小程序框架_生命周期_09

https://developers.weixin.qq.com/miniprogram/dev/framework/app-service/page-life-cycle.html 下图说明了页面 Page 实例的生命周期。

android 自定义小程序容器 android 小程序框架_ide_11

写微信小程序,他的生命周期不能不知道,不然小程序就会出现各种bug而无法解决。

小程序由两大线程组成:负责界面的线程(view thread)和服务线程(appservice thread),各司其职由互相配合

 生命周期演示

在新增了页面的时候 js中会自动生成 记录小程序生命周期的事件

android 自定义小程序容器 android 小程序框架_android 自定义小程序容器_12

在其事件中分别打印对应的语句 进行查看触发的顺序,与上图中一致

onLoad onReady onShow函数触发

 

android 自定义小程序容器 android 小程序框架_生命周期_13

 onHide销毁函数触发

android 自定义小程序容器 android 小程序框架_小程序_14

在test页面新加一个按钮 用来跳转到a页面

<view> <button bindtap="toA">跳转到a页面</button> </view>

在test.js中添加一个toA函数用来跳转

toA:function(event){ wx.navigateTo({ url: '/pages/a/a', }) }

点击跳转到a页面后会触发前三个函数 加载显示与渲染完成

1,点击

android 自定义小程序容器 android 小程序框架_android 自定义小程序容器_15

 2,成功跳转 加载三个函数

android 自定义小程序容器 android 小程序框架_android 自定义小程序容器_16

 3,点击左上角返回页面 销毁此页面时触发函数

android 自定义小程序容器 android 小程序框架_生命周期_17

页面路由

在小程序中所有页面的路由全部由框架进行管理。

页面栈

框架以栈的形式维护了当前的所有页面。 当发生路由切换的时候,页面栈的表现如下:

路由方式

页面栈表现

初始化

新页面入栈

打开新页面

新页面入栈

页面重定向

当前页面出栈,新页面入栈

页面返回

页面不断出栈,直到目标返回页

Tab 切换

页面全部出栈,只留下新的 Tab 页面

重加载

页面全部出栈,只留下新的页面

开发者可以使用 getCurrentPages() 函数获取当前页面栈。

路由方式

对于路由的触发方式以及页面生命周期函数如下:

路由方式

触发时机

路由前页面

路由后页面

初始化

小程序打开的第一个页面

onLoad, onShow

打开新页面

调用 API wx.navigateTo 使用组件 ``

onHide

onLoad, onShow

页面重定向

调用 API wx.redirectTo 使用组件 ``

onUnload

onLoad, onShow

页面返回

调用 API wx.navigateBack 使用组件`` 用户按左上角返回按钮

onUnload

onShow

Tab 切换

调用 API wx.switchTab 使用组件 `` 用户切换 Tab

各种情况请参考下表

重启动

调用 API wx.reLaunch 使用组件 ``

onUnload

onLoad, onShow

Tab 切换对应的生命周期(以 A、B 页面为 Tabbar 页面,C 是从 A 页面打开的页面,D 页面是从 C 页面打开的页面为例):

当前页面

路由后页面

触发的生命周期(按顺序)

A

A

Nothing happend

A

B

A.onHide(), B.onLoad(), B.onShow()

A

B(再次打开)

A.onHide(), B.onShow()

C

A

C.onUnload(), A.onShow()

C

B

C.onUnload(), B.onLoad(), B.onShow()

D

B

D.onUnload(), C.onUnload(), B.onLoad(), B.onShow()

D(从转发进入)

A

D.onUnload(), A.onLoad(), A.onShow()

D(从转发进入)

B

D.onUnload(), B.onLoad(), B.onShow()

注意事项

  • navigateTo, redirectTo 只能打开非 tabBar 页面。
  • a--navigateTo--c, c-->redirectTo-->d
  • switchTab 只能打开 tabBar 页面。
  • reLaunch 可以打开任意页面。
  • 页面底部的 tabBar 由页面决定,即只要是定义为 tabBar 的页面,底部都有 tabBar。
  • 调用页面路由带的参数可以在目标页面的onLoad中获取。

3,模块化

模块化

可以将一些公共的代码抽离成为一个单独的 js 文件,作为一个模块。模块只有通过 module.exports 或者 exports 才能对外暴露接口。

注意:

  • exportsmodule.exports 的一个引用,因此在模块里边随意更改 exports 的指向会造成未知的错误。所以更推荐开发者采用 module.exports 来暴露模块接口,除非你已经清晰知道这两者的关系。
  • 小程序目前不支持直接引入 node_modules , 开发者需要使用到 node_modules 时候建议拷贝出相关的代码到小程序的目录中,或者使用小程序支持的 npm 功能。
// common.js
function sayHello(name) {
  console.log(`Hello ${name} !`)
}
function sayGoodbye(name) {
  console.log(`Goodbye ${name} !`)
}

module.exports.sayHello = sayHello
exports.sayGoodbye = sayGoodbye

在需要使用这些模块的文件中,使用 require 将公共代码引入;也可以使用import导入

var common = require('common.js')
Page({
  helloMINA: function() {
    common.sayHello('MINA')
  },
  goodbyeMINA: function() {
    common.sayGoodbye('MINA')
  }
})

文件作用域

在 JavaScript 文件中声明的变量和函数只在该文件中有效;不同的文件中可以声明相同名字的变量和函数,不会互相影响。

通过全局函数 getApp 可以获取全局的应用实例,如果需要全局的数据可以在 App() 中设置,如:

// app.js
App({
  globalData: 1
})
// a.js
// The localValue can only be used in file a.js.
var localValue = 'a'
// Get the app instance.
var app = getApp()
// Get the global data and change it.
app.globalData++
// b.js
// You can redefine localValue in file b.js, without interference with the localValue in a.js.
var localValue = 'b'
// If a.js it run before b.js, now the globalData shoule be 2.
console.log(getApp().globalData)