微信小程序学习笔记

微信公众平台

  • 注册账号进入后台:设置 -> 开发设置 -> 拿到 AppID(创建小程序项目使用)

  • 每个邮箱仅能申请一个小程序(未被微信公众平台注册,未被微信开放平台注册,未被个人微信号绑定的邮箱)

体验小程序

微信开发者工具

  • 开发者工具

  • 需要使用注册小程序的微信扫码登录

  • 本地开发时:详情-项目配置,将 不校验合法域名勾上

小程序项目结构

代码构成

pages/ ---------------- 页面(组件),所有页面都应该放到这个目录中
index/ ------------- index页面文件夹
index.js ---------- index页面的逻辑代码
index.wxml -------- index页面的HTML结构
index.wxss -------- index页面的CSS样式
index.json -------- 页面配置(可选)
utils/ ---------------- 公共工具(函数)
app.js ---------------- 入口文件
app.json -------------- 全局配置(包括了小程序的所有页面路径、界面表现、网络超时时间、底部 tab 等)
app.wxss -------------- 全局样式(CSS)
project.config.json --- 开发工具配置(例如ES6转ES5、界面颜色、编译配置等)

配置

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

页面配置 配置本页面的窗口表现 , 同全局配置中的 window 项配置,如果页面中的配置与全局配置冲突,是以页面配置为准

页面路径列表-pages 配置项

  • 所有需要展示的页面都要在 app.json 中进行配置,pages 数组的第一项表示进入小程序的默认页面
  • 每一项开头不需要添加 /,否则报错
  • 推荐:所有页面放到 pages 目录中,文件名称与文件夹名称相同
  • 说明:在 app.json 中配置 pages,可以快速创建页面

标签栏 - tabBar 配置

  • 当设置 position 为 top 时,将不会显示 icon
  • tabBar 中的 list 是一个数组,只能配置最少 2 个、最多 5 个 tab,tab 按数组的顺序排序
  • list 中每一个菜单项的pagePath属性必须在 pages 中配置
  • 文字颜色以及选中项文字颜色,只能统一设置不能单独设置
  • 注意:没有出现在 tabBar.listpagePath 页面不展示标签栏

WXML

https://developers.weixin.qq.com/miniprogram/dev/reference/wxml/

数据绑定

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

  • 小程序中插值表达式的特点

    • 插值表达式中可以直接使用 data 中提供的数据
    • 可以在属性中使用
    • 只能使用表达式,不能出现语句(if、for 等)
    • 注意:小程序中的插值表达式不支持方法调用 !!!需要通过特殊的机制来实现该功能
    • 小程序中的数据绑定是单向的,不是双向的
Page({
data: {
msg: 'hello',
isCheck: true
}
})
<text>{{ msg }}</text>
<input type="text" value="{{ msg }}" />
<checkbox checked="{{isCheck}}"></checkbox>

绑定数据的具体类型(Booleal)

<!-- 绑定的是字符串 false,转换成布尔值是 true, checkbox 是选中状态 -->
<checkbox checked="false"></checkbox>

<!-- 绑定的是布尔值 false, checkbox 是未选中状态 -->
<checkbox checked="{{false}}"></checkbox>

<!-- 绑定的是字符串 false, checkbox 是选中状态 -->
<checkbox checked="{{'false'}}"></checkbox>

运算

Page({
data: {
flag: 0,
a: 1,
b: 2,
c: 4,
d: 8,
length: 3,
name: 'zs'
}
})
<!-- 三元运算 -->
<!-- hidden -->
<view hidden="{{flag === 0 ? true : false}}">hidden</view>

<!-- 算数运算 -->
<!-- 13 + 4 + d -->
<view>{{ 10 + a + b}} + {{c}} + d</view>

<!-- checkbox是未选中状态 -->
<checkbox checked="{{a > b}}"></checkbox>

<!-- checkbox是选中状态 -->
<!-- 花括号与引号间有空格,被解析成字符串 -->
<checkbox checked=" {{a > b}}"></checkbox>

<!-- 逻辑判断 -->
<view wx:if="{{length > 5}}">逻辑判断</view>

<!-- 字符串运算 -->
<view>{{ 'name:' + name }}</view>
<!-- name:zs -->

注意: 花括号与引号间不要有空格,否则被解析成字符串

条件渲染

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

wx:if

<view wx:if="{{ isLoading }}">
<text>数据加载中...</text>
</view>
<view wx:else>
<text>搞定啦~</text>
</view>

<!-- 隐藏多个元素,不改变 wxml的层级结构 -->
<block wx:if="{{ isLoading }}">
<text>小明</text>
<text>小红</text>
</block>

hidden

<view hidden="{{ isLoading }}">
<text>搞定啦~</text>
</view>

列表渲染

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

  • wx:for:遍历数组,在元素中通过 index 获取索引号,通过 item 获取当前项
  • wx:for-index="i":替换默认的 index
  • wx:for-item="v":替换默认的 item
  • 注意:遍历时,需要添加 wx:key 属性,来提高渲染性能 (wx:key 的值不需要添加 item.),如 wx:key="id",如果 item 本身是一个唯一的字符串或者数字,可以使用保留关键字 *this(代表在 for 循环中的 item 本身) 作为 key 值
<view wx:for="{{ list }}" wx:for-index="i" wx:for-item="v" wx:key="id">
{{i}}: {{v.message}}
</view>

注意:1. 也可以用来渲染一个对象,index 表示 key,item 表示 value。2. 可以用一个 block 标签包裹,将循环写在 block 标签上,且 block 标签并不会渲染到 dom 中

<block wx:for="{{[1, 2, 3]}}">
<view>{{index}}:</view>
<view>{{item}}</view>
</block>

模板

https://developers.weixin.qq.com/miniprogram/dev/reference/wxml/template.html

定义模板

<!-- name 属性作为模板的名字 -->
<template name="msgItem">
<view>
<text>{{index}}: {{msg}}</text>
</view>
</template>

可以将模板写在单独的一个 wxml 文件中,并通过 import 导入使用

使用模板

使用 is 属性,声明需要的使用的模板,然后将模板所需要的 data 传入

注意:is 属性可以使用 Mustache 语法,来动态决定具体需要渲染哪个模板

<template is="msgItem" data="{{...item}}" />
Page({
data: {
item: {
index: 0,
msg: 'this is a template'
}
}

模板的作用域

模板拥有自己的作用域,只能使用 data 传入的数据以及模板定义文件中定义的 <wxs /> 模块

引用

https://developers.weixin.qq.com/miniprogram/dev/reference/wxml/import.html

import

import可以在该文件中使用目标文件定义的template,如:

在 item.wxml 中定义了一个叫itemtemplate

<!-- item.wxml -->
<template name="item">
<text>{{text}}</text>
</template>

在 index.wxml 中引用了 item.wxml,就可以使用item模板:

<import src="item.wxml" />
<template is="item" data="{{text: 'forbar'}}" />

import 有作用域的概念,即只会 import 目标文件中定义的 template,而不会 import 目标文件 import 的 template。

include

include 可以将目标文件除了 <template/> <wxs/> 外的整个代码引入,相当于是拷贝到 include 位置

WXSS

WXSS(WeiXin Style Sheets),用于描述 WXML 的组件样式

css 相比,WXSS 扩展的特性有:

  • 尺寸单位

    rpx(responsive pixel): 可以根据屏幕宽度进行自适应。规定屏幕宽为 750rpx。如在 iPhone6 上,屏幕宽度为 375px,共有 750 个物理像素,则 750rpx = 375px = 750 物理像素,1rpx = 0.5px = 1 物理像素。

  • 样式导入

    使用 @import 语句可以导入外联样式表,@import 后跟需要导入的外联样式表的相对路径,用;结束

WXSS 中的注释需要使用多行注释

/* */

全局样式、局部样式: app.wxss page.wxss

动态样式:
style 接收动态的样式,在运行时会进行解析,请尽量避免将静态的样式写进 style 中,以免影响渲染速度。

如果通过 wxss 使用背景图片,不能使用本地资源图片,可以使用网络图片,或者 base64;推荐使用<image/>标签来展示图片

<view style="color:{{color}};" />
<view class="{{myclass}}" />

选择器

目前支持的选择器有:.class #id element ::after ::before

基本组件

https://developers.weixin.qq.com/miniprogram/dev/component/

view 组件(标签)

类似于 HTML 中的 div,用来布局

hover-class 属性,指定按下去的样式类,其他属性使用见:https://developers.weixin.qq.com/miniprogram/dev/component/view.html

text 组件

类似于 HTML 中的 span,行内元素

属性 类型 默认值 必填 说明
selectable boolean false 文本是否可选(长按文本)
space string 显示连续空格
decode boolean false 是否解码

详细使用文档: https://developers.weixin.qq.com/miniprogram/dev/component/text.html

注意:如果想要文本选中功能,必须使用 text 标签,并且添加 selectable 属性,除了文本节点以外的其他节点都无法长按选中

text 标签中只能嵌套 text 标签

decode 可以解析的有 &nbsp; &lt; &gt; &amp; &apos; &ensp; &emsp;

可以使用 \n 来换行,在编辑器中按回车键换行也会解析出换行

icon 组件

https://developers.weixin.qq.com/miniprogram/dev/component/icon.html

使用 type 指定 icon 的类型,有效值:success, success_no_circle, info, warn, waiting, cancel, download, search, clear

button 组件

https://developers.weixin.qq.com/miniprogram/dev/component/button.html

注意:如果设置了 type 属性,hover-class 属性会失效

input 组件

输入框。该组件是原生组件

属性:
placeholder-style: 指定 placeholder 的样式
placeholder-class: 默认值 input-placeholder 指定 placeholder 的样式类
maxlength: 默认 140,设置最大输入长度,设置为 -1 的时候不限制最大长度
cursor-spacing: 默认 0,指定光标与键盘的距离,取 input 距离底部的距离和 cursor-spacing 指定的距离的最小值作为光标与键盘的距离
confirm-type: 默认 done,设置键盘右下角按钮的文字,仅在 type=’text’时生效
adjust-position: 默认 true,键盘弹起时,是否自动上推页面

image 图片组件

https://developers.weixin.qq.com/miniprogram/dev/component/image.html

image 标签是 web 中 img 标签和背景图片的结合体

常用属性

src:图片资源地址

mode:图片裁剪、缩放的模式

lazy-load:图片懒加载,在即将进入一定范围(上下三屏)时才开始加载

show-menu-by-longpress: 开启长按图片显示识别小程序码菜单

binderror: 当错误发生时触发,用于图片加载失败时显示默认图片

注意:图片有默认宽高,默认宽高为:320 * 240 px;默认不会保持宽高比

swiper 轮播组件

默认宽度 100%,高度 150px

scroll-view

https://developers.weixin.qq.com/miniprogram/dev/component/scroll-view.html

https://developers.weixin.qq.com/miniprogram/dev/component/navigator.html
https://developers.weixin.qq.com/miniprogram/dev/framework/app-service/route.html

属性 类型 默认值 必填 说明
target string self 在哪个目标上发生跳转,默认当前小程序
url string 当前小程序内的跳转链接
open-type string navigate 跳转方式

open-type 的合法值

说明
navigate 对应 wx.navigateTo
redirect 对应 wx.redirectTo
switchTab 对应 wx.switchTab
reLaunch 对应 wx.reLaunch
navigateBack 对应 wx.navigateBack
exit 退出小程序,target="miniProgram" 时生效

wx.navigateTo ,保留当前页面,跳转到应用内的某个页面。但是不能跳到 tabbar 页面。
wx.redirectTo 的功能,关闭当前页面,跳转到应用内的某个页面。但是不允许跳转到 tabbar 页面。
wx.switchTab 的功能,跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面
wx.reLaunch 的功能,关闭所有页面,打开到应用内的某个页面
wx.navigateBack 的功能,关闭当前页面,返回上一页面或多级页面。可通过 getCurrentPages 获取当前的页面栈,决定需要返回几层。
getCurrentPages

url 可以使用绝对路径或相对路径,使用绝对路径时需要添加 /

<navigator url="/pages/index/index" open-type="navigate">sdfsf</navigator>
<navigator url="./index/index" open-type="navigate">sdfsf</navigator>

自定义组件

https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/
https://developers.weixin.qq.com/miniprogram/dev/reference/api/Component.html

普通页面也可以使用 Component 构造器来创建,提供 observers 支持数据监听,类似 vue 中的 watch

还可以扩展 conputed,类似 vue 计算属性

数据操作

全局数据

app.js

App({
globalData: {
url: 'hhh'
}
})

在 app.js 文件中,直接使用

this.globalData.url // 获取
this.globalData.url = 'qqq' // 修改

在其他非 app.js 文件中使用

let App = getApp()
let url = App.globalData.url // 获取
App.globalData.url = 'hhh' // 修改
App.globalData.name = 'zs' // 添加

页面内数据

获取数据

getMsg () {
console.log(this.data.msg) // 和 vue 中的不同
}

修改数据

  • setData
  • setData():更新数据
    • 说明:将数据从逻辑层发送到视图层(异步),同时改变对应的 this.data 的值(同步)
    • 修改 data 中的数据
    • 更新视图,也就是说:视图中使用该数据的地方会重新渲染
changeMsg () {
this.setData({
name: "jack"
}, function () {
// 回调函数
})
}

注意:小程序中的数据不是双向绑定的,而是单向的!!!所以,无法直接修改 data 中的数据来将数据的变化显示在页面中,即通过 this.data.msg = '修改后的数据' 方式修改数据后,页面中不会显示该数据的变化

  • 文本框操作:
<input value="{{ input }}" bindinput="inputChangeHandle" />
Page({
inputChangeHandle: function(e) {
this.setData({ input: e.detail.value })
}
})

事件处理

https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxml/event.html

  • 绑定事件:bindtapcatchtap
  • 说明:bind 事件绑定不会阻止冒泡事件向上冒泡,catch 事件绑定可以阻止冒泡事件向上冒泡
  • 事件对象可以携带额外信息,如 id, dataset, touches:通过标签的自定义属性data-*,实现给事件传递参数(不能使用函数调用的形式

  • 连字符写法会转换成驼峰写法,而大写字符会自动转成小写字符:data-element-type ,最终会呈现为 event.currentTarget.dataset.elementTypedata-elementType ,最终会呈现为 event.currentTarget.dataset.elementtype

  • mark 也可以用于承载一些自定义数据(类似于 dataset )

<button bindtap="sayHi" data-msg="zs">按钮</button>
Page({
sayHi(event) {
console.log(event)
console.log('单击事件触发了', event.currentTarget.dataset.msg)
}
})

WXS

作用: 辅助构建页面结构的

不支持 es6 语法

<!-- 语法结构 -->
<wxs module="tools">
function fn (arg) {
return arg + 10
}
// 导出一个对象
module.exports = { fn: fn }
</wxs>

<!-- 使用 -->
<view>使用wxs:{{ tools.fn(8) }}</view>

UI 库

  • weui-wsxx

生命周期

两个生命周期:应用生命周期、页面生命周期

  • app 生命周期
  • 页面 生命周期

小程序发送请求

wx.request(Object object)

关于小程序中网络相关 API 的说明

在实际的项目中需要在 开发设置 中配置 服务器域名,然后小程序才能发送请求获取数据,但在开发期间,可以忽略这一步,在开发工具右上角的 详情 菜单中,勾选 不校验安全域名、TLS版本以及HTTPS证书

在小程序不用考虑跨域的问题,因为小程序是基于微信这个客户端

无法在小程序中使用 XHR 对象,发送请求

api

wx.previewImage(Object object) 全屏预览图片

https://developers.weixin.qq.com/miniprogram/dev/api/media/image/wx.previewImage.html

<image src="{{tools.replace(src)}}" bindtap="previewImage" data-current="{{ src }}" data-urls="{{ item.images }}"></image>
// 图片预览
previewImage (e) {
// 获取需要预览的图片链接
let {dataset: { current, urls}} = e.currentTarget

// 将图片替换为大图
current = current.replace('w.h', '1000.1000')
urls = urls.map(item => {
return item.replace('w.h', '1000.1000')
})

// 调用预览图片 API
wx.previewImage({
current, // 当前显示图片的http链接
urls // 需要预览的图片http链接列表
})
}

wx.saveImageToPhotosAlbum 保存图片到相册

https://developers.weixin.qq.com/miniprogram/dev/api/media/image/wx.saveImageToPhotosAlbum.html

wx.pageScrollTo(Object object)

将页面滚动到目标位置

选择节点 wx.createSelectorQuery()

https://developers.weixin.qq.com/miniprogram/dev/api/wxml/wx.createSelectorQuery.html

https://developers.weixin.qq.com/miniprogram/dev/framework/view/selector.html

返回一个 SelectorQuery 对象实例。在自定义组件或包含自定义组件的页面中,应使用 this.createSelectorQuery() 来代替

文件系统

文件系统
https://developers.weixin.qq.com/miniprogram/dev/api/file/wx.saveFile.html
https://developers.weixin.qq.com/miniprogram/dev/framework/ability/file-system.html

上传文件
https://developers.weixin.qq.com/miniprogram/dev/api/network/upload/wx.uploadFile.html

文件管理器
https://developers.weixin.qq.com/miniprogram/dev/api/file/wx.getFileSystemManager.html

页面事件处理函数

onPageScroll(Object)

https://developers.weixin.qq.com/miniprogram/dev/reference/api/Page.html#onPageScroll-Object-object

监听用户滑动页面事件。

Object 参数说明:
scrollTop Number 页面在垂直方向已滚动的距离(单位 px)

onPageScroll(scroll) {
console.log(scroll.scrollTop)
}

小程序中授权功能

  • 打开小程序设置页(wx.openSetting)接口调整
  • openSetting 的问题
  • wepy 爬坑记 - openSetting
wx.getSetting({
success(res) {
console.log('success: ', res)
// 根据获取到的用户授权信息判断用户是否同意过授权
if (res.authSetting['scope.address'] === true) {
// res.authSetting['scope.address'] ===> true
// 已经授权,并且已经同意
// 直接打开 收获地址 页面
wx.chooseAddress({
success(res) {
console.log('是否确认同意授权:', res)
}
})
} else if (res.authSetting['scope.address'] === false) {
// res.authSetting['scope.address'] ===> false
// 已经授权,并切没有同意
// 弹出确认框,引导用户去授权
wx.showModal({
title: '温馨提示',
content: '您需要授权后,才能使用收获地址功能,是否打开授权界面',
success(res) {
if (res.confirm) {
// 点击确定按钮
wx.openSetting({
success(res) {
// console.log(res)
// 此处,可以通过 res.authSetting['scope.address'] 来获取到用户
// 是否同意授权
if (res.authSetting['scope.address']) {
// 用户同意授权小程序使用通讯地址这个开发接口
wx.chooseAddress({
success(res) {
console.log('是否确认同意授权:', res)
}
})
} else {
console.log('用户本次还是不同意小程序使用通讯地址')
}
}
})
} else {
// 点击取消按钮
console.log('取消')
}
}
})
} else {
// res.authSetting['scope.address'] ===> undefined
// 没有授权
// 第一次点击按钮
wx.chooseAddress({
success(res) {
console.log('是否确认同意授权:', res)
}
})
}
}
})

分包加载

https://developers.weixin.qq.com/miniprogram/dev/framework/subpackages.html

与 vue 的区别

  • 小程序中 插值表达式可以用在属性中

  • 小程序中的插值表达式默认不支持方法调用,需要通过特殊机制来实现

<!-- 以下不会再视图中输出内容,也不会报错 -->
<view>{{[1, 2].join('-')}}</view>
  • 小程序中的数据操作

    • 获取数据 this.data.msg
    • 更新数据 this.setData({ msg: 'something' })
  • 绑定布尔值

<!-- vue 中 -->
<xx :xx="true"></xx>

<!-- 小程序中 -->
<xx xx="{{true}}"></xx>
  • 小程序中绑定事件时,不能直接调用事件处理程序,所以传参需要通过自定义属性

  • 遍历数据

    小程序中 wx:for = "lists", 而 Vue 是 v-for = "item in lists"

todomvc 案例

  • 每个框架或库都应该写一个 todomvc,来了解这个框架的使用模式是怎样的

功能

  • 1 欢迎界面(没有任务就展示欢迎界面,有任务就展示任务列表)
    • 注意:欢迎界面 和 任务列表 只能二选一
  • 2 展示任务列表
  • 3 添加任务
    • 剩余任务数量会改变
  • 4 任务状态切换(完成和未完成)
    • 剩余任务数量会改变
    • 当所有的任务都完成,隐藏剩余任务数量展示
  • 5 删除任务
    • 剩余任务数量会改变(删除未完成任务)
  • 6 切换所有任务的选中状态
    • 只要有一项是选中的,那么,就应该让其他项也选中
  • 7 展示清除已完成任务按钮
    • 1 当有已完成的任务,就展示
    • 2 单击清除已完成任务按钮,会清除所有已完成的任务
任务中需要频繁处理的操作:
1 清除已完成任务按钮 的展示和隐藏
2 剩余任务(未完成任务)的展示和隐藏

other

微信小程序 —— button 按钮去除 border 边框:使用 button::after{ border: none; } 来去除边框

button navogator 组件默认有点击态,可以添加 hover-class="none" 去除

getCurrentPages() 方法
https://developers.weixin.qq.com/miniprogram/dev/reference/api/getCurrentPages.html

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

页面间数据传递

let page = getCurrentPages()
console.log(page)
let prevPage = page[page.length - 2]
// 修改上个页面的数据
prevPage.setData({ msg: 'hehehe' }, () => {
wx.navigateBack()
})