微信小程序详解

文章目录

  • 介绍
  • 项目目录结构
  • 小程序与普通网页开发的区别
  • 小程序代码构成
    • JSON的格式:
    • WXML 模板
    • WXSS 样式
    • JS 逻辑交互
    • 程序与页面
  • 小程序的配置
    • 全局配置 app.json
      • entryPagePath
      • pages
      • window
      • tabBar
      • style
    • 页面配置
  • 小程序框架
    • 场景值
    • 逻辑层 App Service
      • 注册小程序
        • ==小程序的生命周期函数==
        • getApp
      • 注册页面
        • 使用 Page 构造器注册页面
          • 页面的初始数据
          • ==页面的生命周期函数==
          • 页面事件处理函数
          • 组件事件处理函数
          • setData
        • 使用 Component 构造器构造页面
        • 在页面中使用 behaviors
        • getCurrentPages()
      • 模块化
      • 文件作用域
      • 其他
    • 视图层 View
      • WXML语法
        • 数据绑定
        • 列表渲染
        • 条件渲染
        • 模板和引用
          • 定义模板和使用模板
          • 模板的作用域
      • WXSS
        • 尺寸单位
        • 样式导入
        • 内联样式
        • 选择器
        • 全局样式与局部样式
      • WXS语法
        • WXS 模块
          • `` 标签
          • .wxs 文件
          • require函数
          • 注意事项
        • JS模块和WXS模块的区分
      • 事件系统
        • 什么是事件
        • 事件的使用方式
        • 事件详解
        • 普通事件绑定
        • 绑定并阻止事件冒泡
        • 互斥事件绑定
        • 事件的捕获阶段
        • 事件对象
        • 事件传参
          • 使用dataset
          • 使用mark
          • dataset和mark的区别
        • DOM、Vue、小程序绑定事件的区别
  • 页面路由
    • 页面栈
    • 路由方式
    • 注意事项
    • 路由传参
  • 自定义组件
    • 创建自定义组件
    • 使用自定义组件
    • 注意事项
    • slot
      • 匿名插槽
      • 具名插槽
    • 组件样式
      • 样式的注意点
      • 组件样式隔离
      • 外部样式类
      • 引用页面或父组件的样式
    • 组件间通信与事件
      • 父传子 properties
      • 子传父 事件
      • 获取组件实例
      • 全局共享的数据
    • ==组件的生命周期函数==
      • 组件生命周期
      • 组件所在页面的生命周期
    • behaviors
    • 组件间关系
    • 数据监听器
      • observers
      • 注意事项

介绍

微信小程序是运行在微信APP内部的子程序,它使用前端技术进行开发,但是又不同于手机APP中的内嵌网页webView。
APP内嵌页面的本质还是一个网页,在APP内部启动了一个简单的浏览器(webView)去打开并显示这个网页。而微信小程序是使用前端技术写成的程序代码,微信在启动小程序时,使用的是原生手机API去渲染小程序。所以小程序相比内嵌页面能够使用更多的手机API(功能)。例如蓝牙功能、地图功能、通讯录等。

网页开发者在开发网页的时候,只需要使用到浏览器,并且搭配上一些辅助工具或者编辑器即可。小程序的开发则有所不同,需要经过申请小程序帐号、安装小程序开发者工具、配置项目等等过程方可完成

开发指南:https://developers.weixin.qq.com/miniprogram/dev/framework/

项目目录结构

一个小程序主体部分由三个文件组成,必须放在项目的根目录,如下:

文件 必需 作用
app.js 小程序逻辑
app.json 小程序公共配置
app.wxss 小程序公共样式表

一个小程序页面由四个文件组成,分别是:

文件类型 必需 作用
js 页面逻辑
wxml 页面结构
json 页面配置
wxss 页面样式表

注意:为了方便开发者减少配置项,描述页面的四个文件必须具有相同的路径与文件名。

  • project.config.json 开发工具的配置文件。

  • sitemap.json 文件用来配置小程序及其页面是否允许被微信索引。

  • app.js 应用程序入口文件,在这个文件中注册小程序实例对象(app)。

  • app.wxss 全局样式文件,定义的样式为全局样式,对所有页面都生效的样式文件。

  • app.json 是当前小程序的全局配置文件,包括了小程序的所有页面路径、界面表现、网络超时时间、底部 tab 等。例如在这个文件中设置页面背景色为红色,那么项目中所有的页面背景色都是红色。

  • pages 是页面目录,其中存放项目的所有页面。每个页面是一个文件夹。文件夹中包含4个文件,分别是

  • xxx.wxml WeiXin Markup Language 微信标记语言。它和html类似,都用于编写页面内容,但是不能使用DOM标签,只能使用微信组件或自定义组件。

  • xxx.wxss WeiXin Style Sheets 微信样式表,和css类似,它兼容大部分css3中的样式,并且增加了一些额外功能。作用域当前页面的样式文件。定义的样式为局部样式,只作用在对应的页面,并会覆盖 app.wxss 中相同的选择器。

  • xxx.js 页面逻辑文件,在这个js文件中,编写本页面的逻辑和数据。

  • xxx.json 本页面的配置文件,页面中配置项会覆盖 app.json 的 window 中相同的配置项,在这个配置文件中,可以设置本页面的导航条,主体颜色,导入自定义组件等。

小程序与普通网页开发的区别

  • 网页开发:
    • 可以使用DOM API 和 BOM API
    • 网页开发者需要面对的环境是各式各样的浏览器,PC 端需要面对 IE、Chrome、QQ浏览器等,在移动端需要面对Safari、Chrome以及 iOS、Android 系统中的各式 WebView 。
  • 小程序开发:
    • 不能使用DOM API 和 BOM API
    • 而小程序开发过程中需要面对的是两大操作系统 iOS 和 Android 的微信客户端,以及用于辅助开发的小程序开发者工具

小程序代码构成

JSON的格式:

JSON的值只能是以下几种数据格式,其他任何格式都会触发报错,例如 JavaScript 中的 undefined。

  1. 数字,包含浮点数和整数
  2. 字符串,需要包裹在双引号中
  3. Bool值,true 或者 false
  4. 数组,需要包裹在方括号中 []
  5. 对象,需要包裹在大括号中 {}
  6. Null

WXML 模板

WXMLHTML 非常相似,WXML 由标签、属性等等构成。但是也有很多不一样的地方:

  • 标签名字有点不一样
    • HTML 的的标签是 div, p, span
    • WXML 用的标签是 view, button, text 等等,这些标签就是小程序给开发者包装好的基本能力,我们还提供了地图、视频、音频等等组件能力。
  • 多了一些 wx:if 这样的属性以及 {{ }} 这样的表达式

WXSS 样式

WXSS 具有 CSS 大部分的特性,小程序在 WXSS 也做了一些扩充和修改。

  1. 新增了尺寸单位。WXSS 在底层支持新的尺寸单位 rpx
  2. 提供了全局的样式和局部样式。你可以写一个 app.wxss 作为全局样式,会作用于当前小程序的所有页面,局部页面样式 page.wxss 仅对当前页面生效。
  3. 此外 WXSS 仅支持部分 CSS 选择器

JS 逻辑交互

和用户做交互:响应用户的点击、获取用户的位置等等。

<button bindtap="tapClick">点击改变messagebutton>
Page({
  data: {
    message: 'Hello World',
  },
  tapClick(){
    this.setData({
      message:'小程序',
    });
  }
})

程序与页面

微信客户端在打开小程序之前,会把整个小程序的代码包下载到本地。

(开发小程序过程中启动小程序)紧接着通过 app.jsonpages 字段就可以知道你当前小程序的所有页面路径:

{
  "pages":[
    "pages/index/index",
    "pages/user/user"
  ]
}

写在 pages 字段的第一个页面就是这个小程序的首页(打开小程序看到的第一个页面)。

小程序的配置

全局配置 app.json

小程序根目录下的 app.json 文件用来对微信小程序进行全局配置,决定页面文件的路径、窗口表现、设置网络超时时间、设置多 tab 等。

全局配置:https://developers.weixin.qq.com/miniprogram/dev/reference/configuration/app.html

entryPagePath

指定小程序的默认启动路径(首页),常见情景是从微信聊天列表页下拉启动、小程序列表启动等。如果不填,将默认为 pages 列表的第一项。不支持带页面路径参数。

pages

用于指定小程序由哪些页面组成,每一项都对应一个页面的 路径(含文件名) 信息。文件名不需要写文件后缀,框架会自动去寻找对应位置的 .json, .js, .wxml, .wxss 四个文件进行处理。

  • 未指定 entryPagePath 时,数组的第一项代表小程序的初始页面(首页)。

  • 创建新的页面,会自动在pages字段中添加页面的路径。

 "pages": [
    "pages/index/index",
    "pages/user/user"
  ],

window

用于设置小程序的状态栏、导航条、标题、窗口背景色。

属性 类型 默认值 描述
navigationBarBackgroundColor HexColor #000000 导航栏背景颜色,如 #000000
navigationBarTextStyle string white 导航栏标题颜色,仅支持 black / white
navigationBarTitleText string 导航栏标题文字内容
navigationStyle string default 导航栏样式,仅支持以下值: default 默认样式 custom 自定义导航栏,只保留右上角胶囊按钮。参见注 2。
backgroundColor HexColor #ffffff 窗口的背景色
backgroundTextStyle string dark 下拉 loading 的样式,仅支持 dark / light
backgroundColorTop string #ffffff 顶部窗口的背景色,仅 iOS 支持
backgroundColorBottom string #ffffff 底部窗口的背景色,仅 iOS 支持
enablePullDownRefresh boolean false 是否开启全局的下拉刷新。 详见 Page.onPullDownRefresh
onReachBottomDistance number 50 页面上拉触底事件触发时距页面底部距离,单位为 px。 详见 Page.onReachBottom
pageOrientation string portrait 屏幕旋转设置,支持 auto / portrait / landscape 详见 响应显示区域变化
restartStrategy string homePage 重新启动策略配置
initialRenderingCache string 页面初始渲染缓存配置,支持 static / dynamic
visualEffectInBackground string none 切入系统后台时,隐藏页面内容,保护用户隐私。支持 hidden / none
handleWebviewPreload string static 控制预加载下个页面的时机。支持 static / manual / auto

tabBar

如果小程序是一个多 tab 应用(客户端窗口的底部或顶部有 tab 栏可以切换页面),可以通过 tabBar 配置项指定 tab 栏的表现,以及 tab 切换时显示的对应页面。

属性 类型 必填 默认值 描述
color HexColor tab 上的文字默认颜色,仅支持十六进制颜色
selectedColor HexColor tab 上的文字选中时的颜色,仅支持十六进制颜色
backgroundColor HexColor tab 的背景色,仅支持十六进制颜色
borderStyle string black tabbar 上边框的颜色, 仅支持 black / white
list Array tab 的列表,详见 list 属性说明,最少 2 个、最多 5 个 tab
position string bottom tabBar 的位置,仅支持 bottom / top
custom boolean false 自定义 tabBar,见详情

其中 list 接受一个数组,只能配置最少 2 个、最多 5 个 tab。tab 按数组的顺序排序,每个项都是一个对象,其属性值如下:

属性 类型 必填 说明
pagePath string 页面路径,必须在 pages 中先定义
text string tab 上按钮文字
iconPath string 图片路径,icon 大小限制为 40kb,建议尺寸为 81px * 81px,不支持网络图片。 positiontop 时,不显示 icon。
selectedIconPath string 选中时的图片路径,icon 大小限制为 40kb,建议尺寸为 81px * 81px,不支持网络图片。 positiontop 时,不显示 icon。

style

微信客户端 7.0 开始,UI 界面进行了大改版。小程序也进行了基础组件的样式升级。app.json 中配置 "style": "v2"可表明启用新版的组件样式。

本次改动涉及的组件有 button icon radio checkbox switch slider。可前往小程序示例进行体验

页面配置

每一个小程序页面也可以使用同名 .json 文件(比如:index页面下的 index.json)来对本页面的窗口表现进行配置,页面中配置项会覆盖 app.jsonwindow 中相同的配置项。

app.json 中的部分配置,也支持对单个页面进行配置,可以在页面对应的 .json 文件来对本页面的表现进行配置。

页面中配置项在当前页面会覆盖 app.json 中相同的配置项(样式相关的配置项属于 app.json 中的 window 属性,但这里不需要额外指定 window 字段。

页面配置:https://developers.weixin.qq.com/miniprogram/dev/reference/configuration/page.html

属性 类型 默认值 描述
navigationBarBackgroundColor HexColor #000000 导航栏背景颜色,如 #000000
navigationBarTextStyle string white 导航栏标题颜色,仅支持 black / white
navigationBarTitleText string 导航栏标题文字内容
navigationStyle string default 导航栏样式,仅支持以下值: default 默认样式 custom 自定义导航栏,只保留右上角胶囊按钮。
backgroundColor HexColor #ffffff 窗口的背景色
backgroundTextStyle string dark 下拉 loading 的样式,仅支持 dark / light
backgroundColorTop string #ffffff 顶部窗口的背景色,仅 iOS 支持
backgroundColorBottom string #ffffff 底部窗口的背景色,仅 iOS 支持
enablePullDownRefresh boolean false 是否开启当前页面下拉刷新。 详见 Page.onPullDownRefresh
onReachBottomDistance number 50 页面上拉触底事件触发时距页面底部距离,单位为px。 详见 Page.onReachBottom
pageOrientation string portrait 屏幕旋转设置,支持 auto / portrait / landscape 详见 响应显示区域变化
disableScroll boolean false 设置为 true 则页面整体不能上下滚动。 只在页面配置中有效,无法在 app.json 中设置
usingComponents Object 页面自定义组件配置
initialRenderingCache string 页面初始渲染缓存配置,支持 static / dynamic
style string default 启用新版的组件样式
singlePage Object 单页模式相关配置
restartStrategy string homePage 重新启动策略配置
handleWebviewPreload string static 控制预加载下个页面的时机。支持 static / manual / auto
  • 注:并不是所有 app.json 中的配置都可以在页面覆盖或单独指定,仅限于本文档包含的选项。
  • 注:iOS/Android 客户端 7.0.0 以下版本,navigationStyle 只在 app.json 中生效。

小程序框架

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

场景值

场景值列表:https://developers.weixin.qq.com/miniprogram/dev/reference/scene-list.html

逻辑层 App Service

小程序开发框架的逻辑层使用 JavaScript 引擎为小程序提供开发者 JavaScript 代码的运行环境以及微信小程序的特有功能。

逻辑层将数据进行处理后发送给视图层,同时接受视图层的事件反馈。

开发者写的所有代码最终将会打包成一份 JavaScript 文件,并在小程序启动的时候运行,直到小程序销毁。这一行为类似 ServiceWorker,所以逻辑层也称之为 App Service。

JavaScript 的基础上,我们增加了一些功能,以方便小程序的开发:

  • 增加 AppPage 方法,进行程序注册和页面注册。
  • 增加 getAppgetCurrentPages 方法,分别用来获取 App 实例和当前页面栈。
  • 提供丰富的 API,如微信用户数据,扫一扫,支付等微信特有能力。
  • 提供模块化能力,每个页面有独立的作用域。

注意:小程序框架的逻辑层并非运行在浏览器中,因此 JavaScript 在 web 中一些能力都无法使用,如 windowdocument 等。

注册小程序

每个小程序都需要在 app.js 中调用 App 方法注册小程序实例,绑定生命周期回调函数、错误监听和页面不存在监听函数等。

文档:https://developers.weixin.qq.com/miniprogram/dev/reference/api/App.html

用法:App(Object object):注册小程序。接受一个 Object 参数,其指定小程序的生命周期回调等。

App() 必须在 app.js 中调用,必须调用且只能调用一次。不然会出现无法预期的后果

小程序的生命周期函数

  • onLaunch(Object object):小程序初始化完成时触发,全局只触发一次。

  • onShow(Object object):小程序启动,或从后台进入前台显示时触发。

  • onHide():小程序从前台进入后台时触发。

小程序的生命周期函数在一个小程序中只存在app.js中。

getApp

整个小程序只有一个 App 实例,是全部页面共享的。开发者可以通过 getApp 方法获取到全局唯一的 App 实例,获取App上的数据或调用开发者注册在 App 上的函数。

用法:getApp() 获取到小程序全局唯一的 App 实例。

注意事项

  • 不要在定义于 App() 内的函数中,或调用 App 前调用 getApp() ,使用 this 就可以拿到 app 实例。
  • 通过 getApp() 获取实例之后,不要私自调用生命周期函数。
App({
  onShow(options){
    // 指向app实例:小程序全局唯一的 App 实例。
    console.log(this);
  },
  // 添加全局共享的数据,是用户自定义的,名字可以是globalData,也可以是其他名字
  // 多个页面共享的数据,通过getApp()获取app实例,通过app实例获取 globalData
  globalData: {
    rootCount: 16,
  }
})
// index.js

const app = getApp();
console.log(app.globalData.rootCount);
// find.js

const app = getApp();
console.log(app.globalData.rootCount);

注册页面

对于小程序中的每个页面,都需要在页面对应的 js 文件中进行注册,指定页面的初始数据、生命周期回调、事件处理函数等。

使用 Page 构造器注册页面

简单的页面可以使用 Page() 进行构造。

用法:Page(Object object):注册小程序中的一个页面。接受一个 Object 类型参数,其指定页面的初始数据、生命周期回调、事件处理函数等。

页面的初始数据
  • data: 页面的初始数据
页面的生命周期函数
  • onLoad:生命周期回调—监听页面加载
  • onShow:生命周期回调—监听页面显示
  • onReady:生命周期回调—监听页面初次渲染完成
  • onHide:生命周期回调—监听页面隐藏
  • onUnload:生命周期回调—监听页面卸载
  • onRouteDone:生命周期回调—路由动画完成时触发。

说明:

  • 在每一个页面的js文件中都有页面自己的生命周期函数。
  • 在生命周期函数中的this指向页面实例,所以生命周期函数不能使用箭头函数
页面事件处理函数
  • onPullDownRefresh:监听用户下拉动作—-刷新页面
    • 需要在app.json的window选项中或页面配置中开启enablePullDownRefresh。
  • onReachBottom:页面上拉触底事件的处理函数—加载更多
    • 可以在app.json的window选项中或页面配置中设置触发距离onReachBottomDistance。
    • 在触发距离内滑动期间,本事件只会被触发一次。
  • onPageScroll:页面滚动触发事件的处理函数
  • onTabItemTap:点击 tab 时触发
  • onSaveExitState:每当小程序可能被销毁之前,页面回调函数 onSaveExitState 会被调用,可以进行退出状态的保存。
组件事件处理函数

Page 中还可以定义组件事件处理函数。在渲染层的组件中加入事件绑定,当事件被触发时,就会执行 Page 中定义的事件处理函数。

  • 在自定义的函数中,this也是指向页面实例,自定义函数不能使用箭头函数
<button bindtap="tapClick">点击改变messagebutton>
Page({
  data: {
    message: 'Hello World',
  },
  // tabClick是自定义的函数
  tapClick(){
    this.setData({
      message:'小程序',
    });

    this.add();// 调用自定义的函数
  },

  add(){
    console.log('add 函数');
  },
})
setData

在小程序中改变data中的数据,需要使用 setData函数,不能直接改变。

setData 函数用于将数据从逻辑层发送到视图层(异步),同时改变对应的 this.data 的值(同步)。

用法:setData(Object data, Function callback)

参数说明

字段 类型 必填 描述
data Object 这次要改变的数据
callback Function setData引起的界面更新渲染完毕后的回调函数
  • Objectkey: value 的形式表示,将 this.data 中的 key 对应的值改变成 value

  • 其中 key 可以以数据路径的形式给出,支持改变数组中的某一项或对象的某个属性,如 array[2].messagea.b.c.d

  • key 并且不需要在 this.data 中预先定义,也可以在this.data中预先定义。

注意:

  1. 直接修改 this.data 而不调用 this.setData 是无法改变页面的状态的,还会造成数据不一致
  2. 仅支持设置可 JSON 化的数据。
  3. 单次设置的数据不能超过1024kB,请尽量避免一次设置过多的数据。
  4. 请不要把 data 中任何一项的 value 设为 undefined ,否则这一项将不被设置并可能遗留一些潜在问题。
Page({
  data: {
    message: 'Hello World',
    num:1,
    arr:[1,2,3],
    obj:{
      name:'张三',
      age: 18,
    }
  },

  tapClick(){
    // 在小程序中改变data中的数据,需要使用 setData函数,不能直接改变this.data
    this.setData({
      message:'小程序',
      // num: 100,
      num: this.data.num + 100,
      // arr:[3,4,5,6],// 改变整个数组
      'arr[1]': 66,// 支持路径的写法
      // obj:{name:'李四', age: 20},// 改变整个对象
      'obj.age': 22,// 支持路径的写法
    });
  })

使用 Component 构造器构造页面

Page 构造器适用于简单的页面。但对于复杂的页面, Page 构造器可能并不好用。

此时,可以使用 Component 构造器来构造页面。 Component 构造器的主要区别是:方法需要放在 methods: { } 里面。

  • 一般的页面通常使用Page注册,一般页面功能复杂的时候,也可以使用Component注册

  • 自定义组件需要使用Component注册

在页面中使用 behaviors

Page和Component注册的页面都可以引用 behaviors 。 behaviors 可以用来让多个页面有相同的数据字段和方法。

behaviors 是用于组件间代码共享的特性,类似于Vue中的 “mixins”。

每个 behavior 可以包含一组属性、数据、生命周期函数和方法。组件引用它时,它的属性、数据和方法会被合并到组件中,生命周期函数也会在对应时机被调用。 每个组件可以引用多个 behaviorbehavior 也可以引用其它 behavior

getCurrentPages()

获取当前页面栈。数组中第一个元素为首页,最后一个元素为当前页面。

注意事项

  • 不要尝试修改页面栈,会导致路由以及页面状态错误。
  • 不要在 App.onLaunch 的时候调用 getCurrentPages(),此时 page 还没有生成。

模块化

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

  • 在小程序中使用的是CommonJS 的模块化规范
    • 导出模块 module.exports = {}
    • 导入模块 const xxx = require('');

文件作用域

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

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

其他

  • console 向调试面板中打印日志。console 是一个全局对象,可以直接访问。
  • 定时器用法不变:setTimeout、setInterval

视图层 View

框架的视图层由 WXML 与 WXSS 编写,由组件来进行展示。

将逻辑层的数据反映成视图,同时将视图层的事件发送给逻辑层。

WXML(WeiXin Markup language) 用于描述页面的结构。

WXS(WeiXin Script) 是小程序的一套脚本语言,结合 WXML,可以构建出页面的结构。

WXSS(WeiXin Style Sheet) 用于描述页面的样式。

组件(Component)是视图的基本组成单元。

WXML语法

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

WXML和html类似,都用于编写页面内容,但是不能使用DOM标签,只能使用微信组件或自定义组件。

数据绑定

WXML 中的动态数据均来自对应 Page 的 data。

简单绑定:数据绑定使用 Mustache 语法(双大括号)将变量包起来。

<view>message = {{message}}view>

文档:https://developers.weixin.qq.com/miniprogram/dev/reference/wxml/data.html

列表渲染

在组件上使用 wx:for 控制属性绑定一个数组,即可使用数组中各项的数据重复渲染该组件。

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

文档:https://developers.weixin.qq.com/miniprogram/dev/reference/wxml/list.html

条件渲染

在框架中,使用 wx:if="" 来判断是否需要渲染该代码块。

文档:https://developers.weixin.qq.com/miniprogram/dev/reference/wxml/conditional.html

模板和引用

WXML提供模板(template),可以在模板中定义代码片段,然后在不同的地方调用。

定义模板和使用模板

定义模板有两种方式:

方式一:直接在index.wxml中定义,并在index.wxml中使用,这种方式只能在当前页面中使用

  • 定义模板:使用 name 属性,作为模板的名字。然后在