小程序开发学习笔记

微信小程序

  • 1. 小程序简介
  • 2. 开始
    • 注册小程序账号
    • 获取小程序的AppID
    • 安装开发者工具
    • 创建小程序项目
  • 3. 小程序代码构成
    • 整体结构
    • page文件
    • json 文件
    • WXML
    • WXSS
    • JS 逻辑交互
  • 4. 小程序的宿主环境
    • 渲染层和逻辑层
    • 小程序启动的过程
    • 页面渲染的过程
    • 组件
      • 视图容器
      • 基础内容组件
      • button 按钮组件
      • image 图片组件
    • API
    • 事件
    • 事件绑定与冒泡捕获
      • Page.prototype.setData
      • dataset
      • bindinput
  • 5. WXML
    • 单向绑定
    • 双向绑定
    • 条件渲染
    • 列表渲染
    • 模板
    • 引用
  • 6. WXSS
    • rpx
    • 样式导入
    • 全局样式与局部样式
  • 7. 全局配置
    • window
    • tabBar
  • 8. 网络数据请求
    • 跳过 request 合法域名校验
    • wx.request
    • 注意事项
  • 9. 页面导航
    • 声明式导航
    • 编程式导航
    • onLoad(Object query)
  • 10. 页面事件
    • onPullDownRefresh

1. 小程序简介

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

1、运行环境不同

网页运行在浏览器环境中,小程序运行在微信环境中。网页开发渲染线程和脚本线程是互斥的,这也是为什么长时间的脚本运行可能会导致页面失去响应,而在小程序中,二者是分开的,分别运行在不同的线程中。
小程序开发学习笔记_第1张图片

2、API不同

由于运行环境的不同,所以小程序中,无法调用 DOM 和 BOM 的 API
但是,小程序中可以调用微信环境提供的各种 API,例如:地理定位、扫码、支付。

3、开发模式不同

网页的开发模式:浏览器 + 代码编辑器
小程序有自己的一套标准开发模式:

  • 申请小程序开发账号
  • 安装小程序开发者工具
  • 创建和配置小程序项目

2. 开始

注册小程序账号

进入小程序注册页 根据指引填写信息和提交相应的资料,就可以拥有自己的小程序帐号。
小程序开发学习笔记_第2张图片

获取小程序的AppID

在小程序管理平台 ,我们可以管理自己的小程序的权限,查看数据报表,发布小程序等操作。

在菜单 开发管理->开发设置->开发者ID可以看到小程序的 AppID ,其相当于小程序平台的一个身份证。
小程序开发学习笔记_第3张图片

安装开发者工具

微信开发者工具是官方推荐使用的小程序开发工具,它提供的主要功能如下:

① 快速创建小程序项目
② 代码的查看和编辑
③ 对小程序功能进行调试
④ 小程序的预览和发布

推荐下载和安装最新的稳定版(Stable Build)的微信开发者工具,进入开发者工具下载网址 下载适合的版本,这里我选择的是Windows64位。
小程序开发学习笔记_第4张图片
下载后按照指示即可完成安装
小程序开发学习笔记_第5张图片

创建小程序项目

进入小程序开发者工具,选择小程序点击+
小程序开发学习笔记_第6张图片
填写项目名称,选择代码存放的硬盘路径,填入刚刚申请到的小程序的 AppID。勾选 “不使用云服务” ,选择JavaScript语言,点击新建。
注意: 要选择一个空的目录才可以创建项目
小程序开发学习笔记_第7张图片
这样,你就得到了你的第一个小程序。
小程序开发学习笔记_第8张图片
可以在模拟器上查看项目效果,也可以在真机上预览项目效果
在这里插入图片描述

3. 小程序代码构成

整体结构

  • pages 用来存放所有小程序的页面
  • utils 用来存放工具性质的模块(例如:格式化时间的自定义模块)
  • app.js 小程序项目的入口文件
  • app.json 小程序项目的全局配置文件
  • app.wxss 小程序项目的全局样式文件
  • project.config.json 工具配置,在工具上做的任何配置都会写入到这个文件。
  • 项目根目录中的 project.config.jsonproject.private.config.json 文件可以对项目进行配置,project.private.config.json 中的相同设置优先级高于 project.config.json
  • sitemap.json 用来配置小程序及其页面是否允许被微信索引
    小程序开发学习笔记_第9张图片

page文件

小程序官方建议把所有小程序的页面,都存放在 pages 目录中,以单独的文件夹存在。每个页面由 4 个基本文件组成,它们分别是:

  • .js 文件:页面的脚本文件,存放页面的数据、事件处理函数等
  • .json 文件:当前页面的配置文件,配置窗口的外观、表现等
  • .wxml文件:充当的就是类似 HTML 的角色,包含页面的模板结构
  • .wxss 文件:当前页面的样式表文件

小程序开发学习笔记_第10张图片

json 文件

app.json 是当前小程序的全局配置,包括了小程序的所有页面路径、窗口外观、界面表现、底部 tab 等。

  • pages:用来记录当前小程序所有页面的路径

  • window:全局定义小程序所有页面的背景色、文字颜色等

  • style:全局定义小程序组件所使用的样式版本

  • sitemapLocation:用来指明 sitemap.json 的位置

    {
    “pages”:[
    “pages/index/index”,
    “pages/logs/logs”
    ],
    “window”:{
    “backgroundTextStyle”:“light”,
    “navigationBarBackgroundColor”: “#fff”,
    “navigationBarTitleText”: “Weixin”,
    “navigationBarTextStyle”:“black”
    },
    “style”: “v2”,
    “sitemapLocation”: “sitemap.json”
    }

project.config.json 是项目配置文件,用来记录我们对小程序开发工具所做的个性化配置,例如:

  • setting 中保存项目的编译设置
  • projectname 中保存的是项目名称,只在新建项目时读取
  • appid 中保存的是项目的 appid,只在新建项目时读取

小程序根目录下的 sitemap.json 文件用于配置小程序及其页面是否允许被微信索引,文件内容为一个 JSON 对象,如果没有 sitemap.json ,则默认为所有页面都允许被索引;

当开发者允许微信索引时,微信会通过爬虫的形式,为小程序的页面内容建立索引。当用户的搜索词条触发该索引时,小程序的页面将可能展示在搜索结果中。

如下,所有页面都会被微信索引(默认情况)

{
  "rules":[{
    "action": "allow",
    "page": "*"
  }]
}

配置 path/to/page 页面被索引,其余页面不被索引

{
  "rules":[{
    "action": "allow",
    "page": "path/to/page"
  }, {
    "action": "disallow",
    "page": "*"
  }]
}

每一个小程序页面也可以使用同名 .json 文件来对本页面的窗口表现进行配置,页面中配置项会覆盖 app.json 的 window 中相同的配置项
小程序开发学习笔记_第11张图片

我们在app.json的pages配置中输入新建的页面,就可以自动生成对应的文件夹。
小程序开发学习笔记_第12张图片
注意:只需要调整 app.json -> pages 数组中页面路径的前后顺序,即可修改项目的首页。小程序会把排在第一位的页面,当作项目首页进行渲染

WXML

WXML(WeiXin Markup Language)是小程序框架设计的一套标签语言,用来构建小程序页面的结构,其作用类似于网页开发中的 HTML。

WXML 和 HTML 的区别

(1) 标签名称不同

  • HTML (div, span, img, a)
  • WXML(view, text, image, navigator)

(2)属性节点不同

(3)提供了类似于 Vue 中的模板语法

  • 数据绑定( {{message}} )
  • 列表渲染(wx:for)
  • 条件渲染(wx:if)

WXSS

WXSS (WeiXin Style Sheets)是一套样式语言,用于描述 WXML 的组件样式,类似于网页开发中的 CSS。

WXSS 和 CSS 的区别

(1)新增了 rpx 尺寸单位

  • CSS 中需要手动进行像素单位换算,例如 rem
  • WXSS 在底层支持新的尺寸单位 rpx,在不同大小的屏幕上小程序会自动进行换算。规定屏幕宽为750rpx。如在 iPhone6 上,屏幕宽度为375px,共有750个物理像素,则750rpx = 375px = 750物理像素,1rpx = 0.5px = 1物理像素。

(2)提供了全局的样式和局部样式

  • 项目根目录中的 app.wxss 会作用于所有小程序页面
  • 局部页面的 .wxss 样式仅对当前页面生效

(3) WXSS 仅支持部分 CSS 选择器

  • .class 和 #id
  • element(组件)
  • 并集选择器、后代选择器
  • ::after 和 ::before 等伪类选择器

JS 逻辑交互

小程序中的 JS 文件分为三大类

  • app.js:是整个小程序项目的入口文件,通过调用 App() 函数来启动整个小程序
  • 页面的 .js 文件:是页面的入口文件,通过调用 Page() 函数来创建并运行页面
  • 普通的 .js 文件:是普通的功能模块文件,用来封装公共的函数或属性供页面使用

4. 小程序的宿主环境

微信客户端给小程序所提供的环境是宿主环境宿主环境(host environment)指的是程序运行所必须的依赖环境。小程序借助宿主环境提供的能力,可以完成许多普通网页无法完成的功能,例如:微信扫码、微信支付、微信登录、地理定位、etc…

小程序开发过程中需要面对的是两大操作系统 iOSAndroid 的微信客户端,以及用于辅助开发的小程序开发者工具。

安卓版的微信 App 是不能在 iOS 环境下运行的,脱离了宿主环境的软件是没有任何意义的!
小程序开发学习笔记_第13张图片

渲染层和逻辑层

小程序的运行环境分成渲染层和逻辑层,其中

  • WXML 模板和 WXSS 样式工作在渲染层
  • JS 脚本工作在逻辑层。

小程序的渲染层和逻辑层分别由2个线程管理

  • 渲染层的界面使用了WebView 进行渲染;
  • 逻辑层采用JsCore线程运行JS脚本。

一个小程序存在多个界面,所以渲染层存在多个WebView线程,这两个线程的通信会经由微信客户端(Native指微信客户端)做中转,逻辑层发送网络请求也经由Native转发,小程序的通信模型下图所示。
小程序开发学习笔记_第14张图片

小程序启动的过程

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

(2)通过 app.json 的 pages 字段就可以知道当前小程序的所有页面路径,第一个页面index.js就是这个小程序的首页 。 微信客户端会把首页的代码装载进来,通过小程序底层的一些机制,渲染出这个首页

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

小程序启动之后,在 app.js 定义的 App 实例的 onLaunch 回调会被执行。
注意:整个小程序只有一个 App 实例,是全部页面共享的。

App({
  onLaunch: function () {
    // 小程序启动之后 触发
  }
})

(3)小程序启动完成

页面渲染的过程

(1)微信客户端会先根据.json 配置生成一个界面,顶部的颜色和文字你都可以在这个 json 文件里边定义好。
(2)紧接着客户端就会装载这个页面的 WXML 结构和 WXSS 样式。
(3)最后客户端会装载.js

// .js 文件
Page({
// 页面的初始数据
  data: {
  },

// 生命周期函数--监听页面加载
  onLoad(options) {
  },

// 生命周期函数--监听页面初次渲染完成
  onReady() {
  },

  // 生命周期函数--监听页面显示
  onShow() {
  },

  // 生命周期函数--监听页面隐藏
  onHide() {
  },
 // 生命周期函数--监听页面卸载
  onUnload() {
  },
// 页面相关事件处理函数--监听用户下拉动作
  onPullDownRefresh() {
  },
// 页面上拉触底事件的处理函数
  onReachBottom() {
  },
//用户点击右上角分享
  onShareAppMessage() {
  }
})

Page 是一个页面构造器,这个构造器就生成了一个页面。在生成页面的时候,小程序框架会把 data 数据和 index.wxml 一起渲染出最终的结构。

组件

小程序中的组件也是由宿主环境提供的,开发者可以基于组件快速搭建出漂亮的页面结构。

像 HTML 的 div, p 等标签一样,在小程序里边,你只需要在 WXML 写上对应的组件标签名字就可以把该组件显示在界面上,

 

官方把小程序的组件分为:

  • 视图容器
  • 基础内容
  • 表单组件
  • 导航组件
  • 媒体组件
  • map 地图组件
  • canvas 画布组件
  • 开放能力
  • 无障碍访问
  • 导航栏

视图容器

1、view

  • 普通视图区域
  • 类似于 HTML 中的 div,是一个块级元素
  • 常用来实现页面的布局效果

WXML

 
   A
   B
   C

WXSS

/* pages/list/list.wxss */
.container1 view{
  width: 100px;
  height: 100px;
  text-align: center;
  line-height: 100px;
}
.container1 view:nth-child(1){
  background-color: lightgreen;
}

.container1 view:nth-child(2){
  background-color: lightpink ;
}
.container1 view:nth-child(3){
  background-color: lightskyblue;
}

.container1{
  display: flex;
  justify-content: space-around;
}

小程序开发学习笔记_第15张图片

2、 scroll-view

  • 可滚动的视图区域
  • 常用来实现滚动列表效果

WXML




 
   A
   B
   C

WXSS

/* pages/list/list.wxss */
.container1 view{
  width: 100px;
  height: 100px;
  text-align: center;
  line-height: 100px;
}
.container1 view:nth-child(1){
  background-color: lightgreen;
}

.container1 view:nth-child(2){
  background-color: lightpink ;
}
.container1 view:nth-child(3){
  background-color: lightskyblue;
}

.container1{
  border: 1px solid red;
  height: 150px;
  width: 100px;
}

小程序开发学习笔记_第16张图片

3、swiperswiper-item

  • 轮播图容器组件 和 轮播图 item 组件

WXML



  
      A
  
  
      B
  
  
      C
  

WXSS

/* pages/list/list.wxss */
.swiper-container{
  height: 150px;
}
.item{
  height: 100%;
  line-height: 150px;
  text-align: center;
}
swiper-item:nth-child(1) .item{
  background-color: lightgreen;
}

swiper-item:nth-child(2) .item{
  background-color: lightpink ;
}
swiper-item:nth-child(3) .item{
  background-color: lightskyblue;
}

小程序开发学习笔记_第17张图片
常见属性:属性

基础内容组件

1、text

  • 文本组件
  • 类似于 HTML 中的 span 标签,是一个行内元素

通过 text 组件的 user-select 属性可以实现长按选中文本内容的效果(其他的不可以):



手机号哈哈哈哈



烤肉哈哈哈哈哈

注意:这里需要用预览实现长按效果,模拟器不行。
在这里插入图片描述

2、rich-text

  • 富文本组件

  • 支持把 HTML 字符串渲染为 WXML 结构

小程序开发学习笔记_第18张图片

button 按钮组件

功能比 HTML 中的 button 按钮丰富,常见属性如下

  • size:default、mini

  • type: primary(绿色)、default(白色)、warn(红色)

  • plain:按钮是否镂空,背景色透明

    hh

image 图片组件

image 组件默认宽度约 300px、高度约 240px




image{
  border: 1px solid red;
  border-style: solid;
}

小程序开发学习笔记_第19张图片
image 组件的 mode 属性用来指定图片的裁剪和缩放模式
小程序开发学习笔记_第20张图片
小程序开发学习笔记_第21张图片
小程序开发学习笔记_第22张图片

API

宿主环境提供了丰富的API,可以很方便调起微信提供的能力。wx对象是小程序的宿主环境所提供的全局对象,几乎所有小程序的API都挂载在wx对象底下(除了Page/App等特殊的构造器)。

1、wx.on* 开头的 API 是监听某个事件发生的API接口,接受一个 Callback 函数作为参数。当该事件触发时,会调用 Callback 函数。

// 监听窗口尺寸变化的事件
wx.onWindowResize(function callback) 

2、 同步 API

  • 以 Sync 结尾的 API 都是同步 API
  • 同步 API 的执行结果,可以通过函数返回值直接获取,如果执行出错会抛出异常
  • wx.setStorageSync('key', 'value') 向本地存储中写入内容

3、异步 API

多数 API 接口为异步接口 ,都接受一个Object作为参数。API的Object参数一般由success、fail、complete三个回调来接收接口调用结果

wx.request({
url: 'test.php',
data: {},
header: { 'content-type': 'application/json' },
success: function(res) {
 // 收到https服务成功后返回
 console.log(res.data)
},
fail: function() {
 // 发生网络错误等情况触发
},
complete: function() {
 // 成功或者失败后触发
}
})

4、wx.get* 开头的API是获取宿主环境数据的接口。
5、wx.set* 开头的API是写入数据到宿主环境的接口。

事件

用户在渲染层的行为反馈以及组件的部分状态反馈抽象为渲染层传递给逻辑层事件
小程序开发学习笔记_第23张图片
事件是通过bindtap这个属性绑定在组件上的,同时在当前页面的Page构造器中定义对应的事件处理函数tapName,当用户点击该view区域时,达到触发条件生成事件tap,该事件处理函数tapName会被执行,同时还会收到一个事件对象event。

WXML


 Click me! 

js文件

// page.js
   Page({
  tapName: function(event) {
    console.log(event)
  }
})

常见的事件类型如下:
小程序开发学习笔记_第24张图片
小程序开发学习笔记_第25张图片

事件绑定与冒泡捕获

以key="value"的形式绑定事件,

  • key以bind或者catch开头,然后跟上事件的类型,如bindtapcatchtouchstart。自基础库版本1.5.0起,bind和catch后可以紧跟一个冒号,其含义不变,如bind:tap、catch:touchstart。同时bind和catch前还可以加上capture-来表示捕获阶段。
  • value是一个字符串,需要在对应的页面Page构造器中定义同名的函数,否则触发事件时在控制台会有报错信息。

bind和capture-bind的含义分别代表事件的冒泡阶段和捕获阶段,其触发的顺序如图
小程序开发学习笔记_第26张图片
点击 inner view 会先后调用handleTap2、handleTap4、handleTap3、handleTap1。


  outer view
  
    inner view
  

bind事件绑定不会阻止冒泡事件向上冒泡,catch事件绑定可以阻止冒泡事件向上冒泡。如果将上面代码中的第一个capture-bind改为capture-catch,将只触发handleTap2(capture-catch将中断捕获阶段和取消冒泡阶段)


  outer view
  
    inner view
  

Page.prototype.setData

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

  • Object 以 key: value 的形式表示,将 this.data 中的 key 对应的值改变成 value。其中 key 可以以数据路径的形式给出,支持改变数组中的某一项或对象的某个属性,如 array[2].messagea.b.c.d,并且不需要在 this.data 中预先定义。

  • 直接修改 this.data 而不调用 this.setData 是无法改变页面的状态的,还会造成数据不一致。

    {{count}}

    Page({
    // 页面的初始数据
    data: {
    count:0
    },
    btnTapHandler(){
    this.setData({
    count:this.data.count+1
    })
    },
    })

dataset

在组件节点中可以自定义数据,然后在事件中可以获取这些自定义的节点数据,用于事件的逻辑处理。

自定义数据以data-开头,多个单词由连字符 - 连接。这种写法中,连字符写法会转换成驼峰写法,而大写字符会自动转成小写字符。如:

  • data-element-type ,最终会呈现为 event.currentTarget.dataset.elementType ;
  • data-elementType ,最终会呈现为 event.currentTarget.dataset.elementtype 。



btnTapHandler(event){
    console.log(event.currentTarget.dataset);
    this.setData({
      count:this.data.count+1
    })
  },

小程序开发学习笔记_第27张图片

bindinput

在小程序中,通过 input 事件来响应文本框的输入事件。键盘输入时触发,event.detail = {value, cursor, keyCode},value为文本框变化后的值,keyCode 为键值。

2.1.0 起支持,处理函数可以直接 return 一个字符串,将替换输入框的内容。




 inputHandler(event){
    console.log(event.detail.value);
  },

5. WXML

单向绑定

WXML

注意:属性值必须被包裹在双引号(或单引号)中

{{info}}

WXSS

data: {
    info:"hello",
    image_src:'../../image/1.jpeg'

  },

小程序开发学习笔记_第28张图片
注意:没有被定义的变量的或者是被设置为 undefined 的变量不会被同步到 wxml 中

双向绑定

在 WXML 中,普通的属性的绑定是单向的。如果用户修改了输入框里的值,却不会同时改变 this.data.value 。


如果需要在用户输入的同时改变 this.data.value ,需要借助简易双向绑定机制。此时,可以在对应项目之前加入model:前缀:


条件渲染

使用 wx:if=“” 来判断是否需要渲染该代码块:

 True 


 1 
 2 
 3 



   view1 
   view2 

在小程序中,直接使用 hidden="{{ condition }}" 也能控制元素的显示与隐藏:


wx:if vs hidden
(1)运行方式不同

  • wx:if 以动态创建和移除元素的方式,控制元素的展示与隐藏
  • hidden 以切换样式的方式(display: none/block;),控制元素的显示与隐藏

(2)使用建议

  • 频繁切换时,建议使用 hidden
  • 控制条件复杂时,建议使用 wx:if 搭配 wx:elif、wx:else 进行展示与隐藏的切换

列表渲染

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

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


{{index}}--{{item}}



data:{
	array:[
      '吃饭',
      '睡觉',
      '学习'
    ]
}

小程序开发学习笔记_第29张图片

  • 使用 wx:for-item 可以指定数组当前元素的变量名,

  • 使用 wx:for-index 可以指定数组当前下标的变量名:

    {{idx}}--{{itemName}}

如果列表中项目的位置会动态改变或者有新的项目添加到列表中,并且希望列表中的项目保持自己的特征和状态(如 input 中的输入内容,switch 的选中状态),需要使用 wx:key 来指定列表中项目的唯一的标识符。


如果列表中项目的位置会动态改变或者有新的项目添加到列表中,并且希望列表中的项目保持自己的特征和状态(如 input 中的输入内容,switch 的选中状态),需要使用 wx:key 来指定列表中项目的唯一的标识符。

wx:key 的值以两种形式提供

  • 字符串,代表在 for 循环的 array 中 item 的某个 property,该 property 的值需要是列表中唯一的字符串或数字,且不能动态改变。
  • 保留关键字 *this 代表在 for 循环中的 item 本身,这种表示需要 item 本身是一个唯一的字符串或者数字。

当数据改变触发渲染层重新渲染的时候,会校正带有 key 的组件,框架会确保他们被重新排序,而不是重新创建,以确保使组件保持自身的状态,并且提高列表渲染时的效率。如果明确知道该列表是静态,或者不必关注其顺序,可以选择忽略。

 {{item.id}} 

 {{item}} 


data: {
    objectArray: [
      {id: 5, unique: 'unique_5'},
      {id: 4, unique: 'unique_4'},
      {id: 3, unique: 'unique_3'},
      {id: 2, unique: 'unique_2'},
      {id: 1, unique: 'unique_1'},
      {id: 0, unique: 'unique_0'},
    ],
    numberArray: [1, 2, 3, 4]
  },

模板

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