微信小程序学习笔记

补一补微信小程序!

学习链接

文档:
小程序框架参考文档

目录结构

  • 文件构成

小程序组件参考文档 // 可调用参数
小程序API参考文档 // 调用方法

小程序服务端API参考文档
微信开发者工具参考文档

工具:
微信开发者工具

基础学习

json配置

小程序配置 app.json

在项目的根目录有一个 app.json 和 project.config.json,此外在 pages/logs 目录下还有一个 logs.json

还需要注意的是 JSON 文件中无法使用注释,试图添加注释将会引发报错。

app.json

是当前小程序的全局配置,包括了小程序的所有页面路径、界面表现、网络超时时间、底部 tab等。
QuickStart 项目里边的 app.json 配置内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
// 用于描述当前小程序所有页面路径,这是为了让微信客户端知道当前你的小程序页面定义在哪个目录。
"pages":[
"pages/index/index",
"pages/logs/logs"
],
// window字段 —— 定义小程序所有页面的顶部背景颜色,文字颜色定义等。
"window":{
"backgroundTextStyle":"light",
"navigationBarBackgroundColor": "#fff",
"navigationBarTitleText": "Weixin",
"navigationBarTextStyle":"black"
}
}

project.config.json

工具配置

通常大家在使用一个工具的时候,都会针对各自喜好做一些个性化配置,
例如界面颜色、编译配置等等,当你换了另外一台电脑重新安装工具的时候,你还要重新配置。

考虑到这点,小程序开发者工具在每个项目的根目录都会生成一个 project.config.json,
你在工具上做的任何配置都会写入到这个文件,当你重新安装工具或者换电脑工作时,
你只要载入同一个项目的代码包,开发者工具就自动会帮你恢复到当时你开发项目时的个性化配置,
其中会包括编辑器的颜色、代码上传时自动压缩等等一系列选项。

page.json

这里的 page.json 其实用来表示 pages/logs 目录下的 logs.json 这类和小程序页面相关的配置。

如果你整个小程序的风格是蓝色调,那么你可以在 app.json 里边声明顶部颜色是蓝色即可。
实际情况可能不是这样,可能你小程序里边的每个页面都有不一样的色调来区分不同功能模块
因此我们提供了 page.json,让开发者可以独立定义每个页面的一些属性,
例如刚刚说的顶部颜色、是否允许下拉刷新等等。

WXML 模板

WXML 充当的就是类似 HTML 的角色

1
2
3
4
5
6
7
8
9
10
11
12
<view class="container">
<view class="userinfo">
<button wx:if="{ {!hasUserInfo && canIUse} }"> 获取头像昵称 </button>
<block wx:else>
<image src="{ {userInfo.avatarUrl} }" background-size="cover"></image>
<text class="userinfo-nickname">{ {userInfo.nickName} }</text>
</block>
</view>
<view class="usermotto">
<text class="user-motto">{ {motto} }</text>
</view>
</view>

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

  1. 标签名字有点不一样
    WXML 用的标签是 view, button, text 等等,这些标签就是小程序给开发者包装好的基本能力,
    我们还提供了地图、视频、音频等等组件能力。

  2. 多了一些 wx:if 这样的属性以及 { { } } 这样的表达式
    MVVM 的开发模式

通过 {{ }} 的语法把一个变量绑定到界面上,我们称为数据绑定

仅仅通过数据绑定还不够完整的描述状态和界面的关系,
还需要 if/else, for等控制能力,在小程序里边,这些控制能力都用 **wx:**开头的属性来表达。

WXSS 样式

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

  1. 新增了尺寸单位
    WXSS 在底层支持新的尺寸单位 rpx ,开发者可以免去换算的烦恼,
    只要交给小程序底层来换算即可,由于换算采用的浮点数运算,所以运算结果会和预期结果有一点点偏差。

  2. 提供了全局的样式和局部样式
    你可以写一个 app.wxss 作为全局样式,会作用于当前小程序的所有页面,
    局部页面样式 page.wxss 仅对当前页面生效。

  3. 此外 WXSS 仅支持部分 CSS 选择器

JS 逻辑交互

阅读小程序的API。。
事件

渲染层和逻辑层

小程序的运行环境分成渲染层和逻辑层,其中 WXML 模板和 WXSS 样式工作在渲染层,JS 脚本工作在逻辑层。

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

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

一个小程序存在多个界面,所以渲染层存在多个WebView线程,
这两个线程的通信会经由微信客户端(下文中也会采用Native来代指微信客户端)做中转,
逻辑层发送网络请求也经由Native转发,小程序的通信模型下图所示。

02

程序与页面

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

紧接着通过 app.json 的 pages 字段就可以知道你当前小程序的所有页面路径:

1
2
3
4
5
6
{
"pages":[
"pages/index/index",//写在 pages 字段的第一个页面就是这个小程序的首页(打开小程序看到的第一个页面)。
"pages/logs/logs"
]
}

小程序启动之后,在 app.js 定义的 App 实例的 onLaunch 回调会被执行:

1
2
3
4
5
App({
onLaunch: function () {
// 小程序启动之后 触发
}
})

简单看看小程序的一个页面是怎么写的

pages/logs/logs 下其实是包括了4种文件的

微信客户端会先根据 logs.json 配置生成一个界面
顶部的颜色和文字你都可以在这个 json 文件里边定义好

客户端就会装载这个页面的 WXML 结构和 WXSS 样式。

最后客户端会装载 logs.js

在渲染完界面之后,页面实例就会收到一个 onLoad 的回调,你可以在这个回调处理你的逻辑。
注册页面

组件

需要在界面上显示地图,你只需要这样写即可
<map></map>

传值
<map longitude="广州经度" latitude="广州纬度"></map>

用户点击了地图上的某个标记
你也可以通过 style 或者 class 来控制组件的外层样式
<map bindmarkertap="markertap" longitude="广州经度" latitude="广州纬度"></map>

API

开发者可以很方便的调起微信提供的能力
小程序的API

要获取用户的地理位置

1
2
3
4
5
6
7
wx.getLocation({
type: 'wgs84',
success: (res) => {
var latitude = res.latitude // 纬度
var longitude = res.longitude // 经度
}
})

调用微信扫一扫能力

1
2
3
4
5
wx.scanCode({
success: (res) => {
console.log(res)
}
})

小程序框架

逻辑层 - js

  • 注册小程序 // 整个小程序只有一个 App 实例,是全部页面共享,生命周期等
  • 注册页面 // 页面的初始数据、生命周期回调
  • 页面生命周期
  • 页面路由 // 可以使用 getCurrentPages() 函数获取当前页面栈。
  • 模块化 // 可以将一些公共的代码抽离成为一个单独的 js 文件,作为一个模块。
  • API // 事件监听 API // 同步 API // 异步 API

视图层 - 结构 + 样式

  • WXML // 数据绑定 // 列表渲染 // 条件渲染 // 模板
  • WXSS // 尺寸单位 // 样式导入 // 内联样式 // 选择器 // 全局样式与局部样式
  • WXS // 页面模板???
  • 事件系统
  • 简易双向绑定
  • 基础组件 // 组件内容
  • 获取界面上的节点信息
  • 响应显示区域变化 // 支持屏幕旋转
  • 分栏模式
  • 动画 // 通常可以使用 CSS 渐变 和 CSS 动画 来创建简易的界面动画。
  • 初始渲染缓存

入门项目

01

项目地址

学习链接

文件结构

// 全局
app.js // onLaunch / getUserInfo 初始逻辑
app.json // 第一个加载它!包含pages(路由) / window(名字)
app.wxss // 全局样式
project.config.json // 个性化配置

// 局部
// 自动引入当前文件?
index

  • index.js ////获取应用实例 var app = getApp() // 执行周期函数,获取当前数据
  • index.wxml // 页面结构 / 组件
  • index.wxss // 当前样式 ? 怎么引入的。。

// 日志
logs

  • logs.js
  • logs.json
  • logs.wxml
  • logs.wxss

文件详情

渲染层 / 逻辑层

app.json

// 第一个读取,显示标题 + 颜色
// 可以看到路由信息

1
2
3
4
5
6
7
8
9
10
11
12
13
{
"pages":[
"pages/index/index",
"pages/logs/logs"
],
"window":{
"backgroundTextStyle":"light",
"navigationBarBackgroundColor": "#fff",
"navigationBarTitleText": "米家商城", // 标题
"navigationBarTextStyle":"black"
}
}

app.wxss

全局样式 - 公共样式

1
2
3
4
5
6
.container {
display: flex;
flex-direction: column;
min-height: 100%;
}

app.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
//app.js
App({
onLaunch: function () { // 初始化
//调用API从本地缓存中获取数据
var logs = wx.getStorageSync('logs') || []
logs.unshift(Date.now())
wx.setStorageSync('logs', logs)
},
getUserInfo:function(cb){ // 调用API
var that = this;
if(this.globalData.userInfo){ // 存在
typeof cb == "function" && cb(this.globalData.userInfo) // 回调
}else{
//调用登录接口
wx.login({
success: function () {
wx.getUserInfo({
success: function (res) {
that.globalData.userInfo = res.userInfo;
typeof cb == "function" && cb(that.globalData.userInfo)
}
})
}
});
}
},
globalData:{ // 数据集
userInfo:null
}
})

index.wxml

首页内容

组件

swiper
滑块视图容器。其中只可放置swiper-item组件,否则会导致未定义的行为。

  • indicator-dots - 是否显示面板指示点
  • autoplay 自动播放导致swiper变化;
  • interval - 自动切换时间间隔
  • duration - 滑动动画时长

block wx:for
也可以将 wx:for 用在标签上,以渲染一个包含多节点的结构块。

view

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<!--index.wxml-->
<view class="container"> // 使用全局样式

// 使用swiper组件
<swiper indicator-dots="{{indicatorDots}}"
autoplay="{{autoplay}}" interval="{{interval}}" duration="{{duration}}">

<block wx:for-items="{{banner_list[0].banner}}">
// 展示内容
<swiper-item>
<image src="{{item.pic_url}}" class="slide-image" />
</swiper-item>
</block>
</swiper>

<view>
<view class='menueview' > // 这里没有信息。。
<block wx:for-items="{{banner_list[1].banner}}">
<image src="{{item.pic_url}}" class="menue-image" />
</block>
</view>
</view>

<view class='separator'></view> // 画横线

<view class='floortitle'> // 标题
<view class='floortitlemoreicon'>热卖商品</view>
<view class='floortitlemoretext'>更多> </view>
</view>

<view class='hotgoodcontainer'> // 展示商品
<view class='gooditem' wx:for="{{hotgoods}}" wx:for-index="idx" wx:for-item="good">
<view class='imgview'>
<image class='productimg' src='{{good.pic_url}}'/>
</view>
<view>{{good.name}}</view>
</view>
</view>
</view>

index.wxss

局部样式

index.js

可以使用当前的生命周期

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
//index.js
//获取应用实例
var app = getApp()
Page({
data: {
motto: 'MiHome_Store',
userInfo: {},
indicatorDots: true,
autoplay: true,
interval: 3000,
duration: 100,
"banner_list": [
{
"banner": [
{
"pic_url": "http://static.home.mi.com/app/shop/img?id=shop_904608692a4d8415d0de39a0a5897e80.jpeg&w=1080&h=600&crop=a_0_120_1080_480&t=webp&z=1.15&q=78",
},
{
"pic_url": "http://static.home.mi.com/app/shop/img?id=shop_0f5e43035a8b8d27a4b6f315d222fd9b.jpeg&w=1080&h=600&crop=a_0_120_1080_480&t=webp&z=1.15&q=78",
},
{
"pic_url": "http://static.home.mi.com/app/shop/img?id=shop_4ba3d814639ab27570f174467133619f.png&w=1080&h=600&crop=a_0_120_1080_480&t=webp&z=1.15&q=78",
},
{
"pic_url": "http://static.home.mi.com/app/shop/img?id=shop_91f29509f14ea243958285aaf5d5b640.jpeg&w=1080&h=600&crop=a_0_120_1080_480&t=webp&z=1.15&q=78",
},
{
"pic_url": "http://static.home.mi.com/app/shop/img?id=shop_5c752db8097555831469356f5f389078.jpeg&w=1080&h=600&crop=a_0_120_1080_480&t=webp&z=1.15&q=78",
}
]
},
{
"banner": [
{
"pic_url": "http://static.home.mi.com/app/shop/img?id=shop_3237b46c5de819816125d88e9d06b7bf.jpg&crop=a_0_120_1080_480&t=webp&z=1.15&q=78",
},
{
"pic_url": "http://static.home.mi.com/app/shop/img?id=shop_c02bce3048058edb194dc3efb230d06b.jpg&crop=a_0_120_1080_480&t=webp&z=1.15&q=78",
},
{
"pic_url": "http://static.home.mi.com/app/shop/img?id=shop_45b3c9ed56aef44994176b50ae5d8a69.jpg&crop=a_0_120_1080_480&t=webp&z=1.15&q=78",
},
{
"pic_url": "http://static.home.mi.com/app/shop/img?id=shop_95583f54ee857e8fa5f4cf1b9f791a74.jpg&crop=a_0_120_1080_480&t=webp&z=1.15&q=78",

}
]
}
],
hotgoods: [
{
"name": "90分轻薄羽绒服",
"summary": "防钻绒工艺,保暖更锁温,备好深秋暖意",
"ext_tag": "http://static.home.mi.com/app/shop/img?id=shop_9d57f6e89d1f560b7bce31e0b85a7285.png&w=420&h=240&crop=a_0_120_1080_480&t=png",
"pic_url": "http://static.home.mi.com/app/shop/img?id=shop_48ebe9e693ade1766877e0f8adf425f7.png&w=420&h=240&crop=a_90_0_240_240"
},
{
"name": "红米Note 3",
"summary": "金属机身,指纹解锁,4000mAh大电池",
"ext_tag": "http://static.home.mi.com/app/shop/img?id=shop_d65477ca8db6626da323554e132d7de9.png&w=420&h=240&crop=a_0_120_1080_480&t=png",
"pic_url": "http://static.home.mi.com/app/shop/img?id=shop_c2cf209c66a22818c7f5c269f6bbff12.jpeg&w=420&h=240&crop=a_90_0_240_240",
"url": "http://home.mi.com/shop/detail?gid=95"
},
{
"name": "小米手机5",
"summary": "骁龙820处理器,4轴防抖相机",
"ext_tag": "http://static.home.mi.com/app/shop/img?id=shop_34699befd5c2de3a028eb987fea574e9.png&w=420&h=240&crop=a_0_120_1080_480&t=png",
"pic_url": "http://static.home.mi.com/app/shop/img?id=shop_8dec2f08e5dd9d08b440f77a36e39e16.png&w=420&h=240&crop=a_90_0_240_240"
},
{
"name": "小米Max",
"pic_url": "http://static.home.mi.com/app/shop/img?id=shop_35a026ff12d476496f91d121911af0ce.jpg&crop=a_90_0_240_240",
"summary": "6.44寸大屏黄金尺寸,买赠智能显示保护套",
"ext_tag": "http://static.home.mi.com/app/shop/img?id=shop_86f01fa8cea034deb1dce44c0385baab.png&w=420&h=240&crop=a_0_120_1080_480&t=png"
},
{
"name": "最生活毛巾",
"summary": "精选阿瓦提长绒棉,瑞典抗菌科技,3条/包",
"ext_tag": "http://static.home.mi.com/app/shop/img?id=shop_26beb8c609406d060c57b7cdc9d2627f.png&w=420&h=240&crop=a_0_120_1080_480&t=png",
"pic_url": "http://static.home.mi.com/app/shop/img?id=shop_1e29af11fa83139dd305d61cb83c94ac.jpeg&w=420&h=240&crop=a_90_0_240_240"
},
{
"name": "小米空气净化器 2",
"summary": "全新空气增压系统,净化性能高达 310m³/h",
"pic_url": "http://static.home.mi.com/app/shop/img?id=shop_0b23f4b364ee73bc86b280cc7397638c.jpg&w=420&h=240&crop=a_90_0_240_240"
}
]
},
//事件处理函数
bindViewTap: function () {
wx.navigateTo({
url: '../logs/logs'
})
},
onLoad: function () {
console.log('onLoad')
var that = this
//调用应用实例的方法获取全局数据
app.getUserInfo(function (userInfo) {
//更新数据
that.setData({
userInfo: userInfo
})
that.update()
})
}
})