写在最前

本文总结微信小程序开发中的基础语法知识

一、文件结构

1. 主要文件类型

  • .wxml: 页面结构文件(类似HTML)
  • .wxss: 样式文件(类似CSS)
  • .js: 逻辑文件
  • .json: 配置文件

2. 项目结构

1
2
3
4
5
6
7
├── pages // 页面文件夹
│ ├── index // 首页
│ └── logs // 日志页
├── utils // 工具函数
├── app.js // 全局逻辑
├── app.json // 全局配置
└── app.wxss // 全局样式

二、WXML语法

1. 数据绑定

1
2
3
<view>{{ message }}</view>
<view>{{ object.key }}</view>
<view>{{ array[0] }}</view>

2. 列表渲染

1
2
3
<view wx:for="{{array}}" wx:key="unique">
{{item}}
</view>

3. 条件渲染

1
2
3
<view wx:if="{{condition}}">True</view>
<view wx:elif="{{condition}}">Else if</view>
<view wx:else>Else</view>

4. 事件绑定

1
2
<button bindtap="handleClick">点击</button>
<input bindinput="handleInput" />

5. 模板使用

1
2
3
4
5
6
7
8
9
<!-- 定义模板 -->
<template name="msgItem">
<view>
<text>{{index}}: {{msg}}</text>
</view>
</template>

<!-- 使用模板 -->
<template is="msgItem" data="{{...item}}"/>

6. 引用

1
2
3
<!-- 引入文件 -->
<import src="template.wxml"/>
<include src="header.wxml"/>

三、WXSS样式

1. 尺寸单位

1
2
3
4
5
.container {
width: 750rpx; /* rpx是响应式单位,750rpx = 屏幕宽度 */
height: 100vh; /* vh表示视口高度 */
font-size: 28rpx; /* 一般字体大小 */
}

2. 选择器

1
2
3
4
.class-name {} /* 类选择器 */
#id-name {} /* ID选择器 */
view {} /* 标签选择器 */
.parent .child {} /* 后代选择器 */

3. 样式导入

1
@import "common.wxss";

4. 常用布局

1
2
3
4
5
6
7
8
9
10
11
12
13
/* flex布局 */
.flex-container {
display: flex;
justify-content: space-between;
align-items: center;
}

/* grid布局 */
.grid-container {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20rpx;
}

四、JS逻辑

1. 页面配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Page({
data: {
message: 'Hello',
list: []
},
// 生命周期函数
onLoad() {
// 页面加载时执行
},
onShow() {
// 页面显示时执行
},
// 自定义函数
handleClick() {
this.setData({
message: 'World'
})
}
})

2. 数据操作

1
2
3
4
5
6
7
8
// 修改数据
this.setData({
'message': 'new value',
'object.key': 'value',
'array[0]': 'value'
})
// 获取数据
const value = this.data.message

3. 网络请求

1
2
3
4
5
6
7
8
9
10
11
12
13
wx.request({
url: 'https://api.example.com/data',
method: 'GET',
data: {
id: 1
},
success(res) {
console.log(res.data)
},
fail(err) {
console.error(err)
}
})

4. 生命周期函数

1
2
3
4
5
6
7
8
9
10
Page({
onLoad(options) {}, // 页面加载
onShow() {}, // 页面显示
onReady() {}, // 页面初次渲染完成
onHide() {}, // 页面隐藏
onUnload() {}, // 页面卸载
onPullDownRefresh() {}, // 下拉刷新
onReachBottom() {}, // 上拉触底
onShareAppMessage() {} // 用户分享
})

五、常用API

1. 界面交互

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 显示提示框
wx.showToast({
title: '成功',
icon: 'success'
})
// 显示加载框
wx.showLoading({
title: '加载中'
})
// 显示模态框
wx.showModal({
title: '提示',
content: '确认删除?'
})

2. 路由跳转

1
2
3
4
5
6
7
8
9
10
// 保留当前页面
wx.navigateTo({
url: '/pages/detail/detail?id=1'
})
// 关闭当前页面
wx.redirectTo({
url: '/pages/index/index'
})
// 返回上一页
wx.navigateBack()

3. 数据存储

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 存储数据
wx.setStorage({
key: 'userInfo',
data: {
name: 'test'
}
})
// 获取数据
wx.getStorage({
key: 'userInfo',
success(res) {
console.log(res.data)
}
})

4. 图片操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 选择图片
wx.chooseImage({
count: 1,
sizeType: ['original', 'compressed'],
sourceType: ['album', 'camera'],
success(res) {
const tempFilePaths = res.tempFilePaths
}
})

// 预览图片
wx.previewImage({
urls: ['url1', 'url2']
})

5. 位置服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 获取位置
wx.getLocation({
type: 'gcj02',
success(res) {
const {latitude, longitude} = res
}
})

// 打开位置
wx.openLocation({
latitude,
longitude,
scale: 18
})

6. 设备信息

1
2
3
4
5
6
7
8
9
10
11
12
// 获取系统信息
wx.getSystemInfo({
success(res) {
console.log(res.model)
console.log(res.pixelRatio)
console.log(res.windowWidth)
console.log(res.windowHeight)
console.log(res.language)
console.log(res.version)
console.log(res.platform)
}
})

六、组件系统

1. 视图容器

1
2
3
4
5
6

<view></view> <!-- 块级元素 -->
<scroll-view></scroll-view> <!-- 可滚动视图 -->
<swiper></swiper> <!-- 轮播图 -->
<movable-view></movable-view> <!-- 可移动视图 -->
<cover-view></cover-view> <!-- 覆盖原生组件 -->

2. 基础内容

1
2
3
4
<text></text>           
<rich-text></rich-text> <!-- 富文本 -->
<icon></icon> <!-- 图标 -->
<progress></progress> <!-- 进度条 -->

3. 表单组件

1
2
3
4
5
6
7
8
9
10

<button></button>
<form></form>
<input></input>
<textarea></textarea> <!-- 多行输入 -->
<checkbox></checkbox> <!-- 复选框 -->
<radio></radio> <!-- 单选框 -->
<picker></picker> <!-- 选择器 -->
<slider></slider> <!-- 滑动选择器 -->
<switch></switch> <!-- 开关选择器 -->

4. 媒体组件

1
2
3
4
5
6
7

<image></image>
<video></video>
<audio></audio>
<camera></camera>
<live-player></live-player> <!-- 直播播放 -->
<live-pusher></live-pusher> <!-- 直播推流 -->

七、自定义组件

1. 组件定义

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
// components/custom/custom.js
Component({
// 组件属性
properties: {
title: {
type: String,
value: ''
}
},

// 组件内部数据
data: {
count: 0
},

// 组件方法
methods: {
handleTap() {
this.setData({
count: this.data.count + 1
})
// 触发自定义事件
this.triggerEvent('customEvent', {
count: this.data.count
})
}
},

// 生命周期
lifetimes: {
created() {},
attached() {},
detached() {}
},

// 页面生命周期
pageLifetimes: {
show() {},
hide() {}
}
})

2. 组件使用

1
2
3
4
5
{
"usingComponents": {
"custom": "/components/custom/custom"
}
}
1
<custom title="标题" bind:customEvent="onCustomEvent"/>

八、事件系统

1. 事件类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!-- 点击事件 -->
<view bindtap="handleTap">点击</view>
<view catchtap="handleTap">阻止冒泡的点击</view>

<!-- 长按事件 -->
<view bindlongpress="handleLongPress">长按</view>

<!-- 触摸事件 -->
<view
bindtouchstart="handleTouchStart"
bindtouchmove="handleTouchMove"
bindtouchend="handleTouchEnd">
触摸
</view>

<!-- 输入事件 -->
<input bindinput="handleInput" bindfocus="handleFocus" bindblur="handleBlur"/>

2. 事件对象

1
2
3
4
5
6
7
8
9
Page({
handleTap(e) {
console.log(e.type) // 事件类型
console.log(e.target) // 触发事件的组件
console.log(e.currentTarget) // 事件绑定的组件
console.log(e.detail) // 额外信息
console.log(e.touches) // 触摸点信息
}
})

九、页面通信

1. 页面间通信

1
2
3
4
5
6
7
8
9
10
11
// 页面A: 传递参数
wx.navigateTo({
url: '/pages/pageB/pageB?id=1&name=test'
})

// 页面B: 接收参数
Page({
onLoad(options) {
console.log(options.id, options.name)
}
})

2. 组件通信

1
2
3
4
5
6
7
8
9
10
// 父组件向子组件传值
<custom-component prop-a="{{valueA}}" bind:myevent="onMyEvent"/>

// 子组件向父组件传值
this.triggerEvent('myevent', { data: 'value' })

// 父组件接收
onMyEvent(e) {
console.log(e.detail.data)
}

3. 全局状态管理

1
2
3
4
5
6
7
8
9
10
// app.js
App({
globalData: {
userInfo: null
}
})

// 页面中使用
const app = getApp()
console.log(app.globalData.userInfo)

十、小程序登录流程

1. 登录流程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 1. 获取code
wx.login({
success(res) {
if (res.code) {
// 2. 发送code到后端
wx.request({
url: 'https://api.example.com/login',
data: {
code: res.code
},
success(res) {
// 3. 保存登录状态
wx.setStorageSync('token', res.data.token)
}
})
}
}
})

2. 用户信息获取

1
2
3
4
5
6
7
8
9
10
// 获取用户信息
wx.getUserProfile({
desc: '用于完善会员资料',
success: (res) => {
console.log(res.userInfo)
},
fail: (err) => {
console.error(err)
}
})

十一、性能优化

1. 启动优化

1
2
3
4
5
6
7
8
9
10
11
12
// 分包加载
{
"subpackages": [
{
"root": "packageA",
"pages": [
"pages/cat",
"pages/dog"
]
}
]
}

2. 渲染优化

1
2
3
4
5
6
7
8
9
<!-- 使用懒加载 -->
<image lazy-load src="{{imageUrl}}"/>

<!-- 长列表优化 -->
<scroll-view bindscrolltolower="loadMore">
<view wx:for="{{list}}" wx:key="id">
{{item.name}}
</view>
</scroll-view>

3. 内存优化

1
2
3
4
5
6
7
8
9
10
11
12
13
// 及时清理不需要的数据
onUnload() {
this.setData({
list: []
})
}

// 合并setData调用
this.setData({
'a': 1,
'b': 2,
'c': 3
})

十二、常见问题

1. 网络请求

1
2
3
4
5
6
7
8
9
10
11
12
13
// 配置请求拦截
const request = (options) => {
return new Promise((resolve, reject) => {
wx.request({
...options,
header: {
'Authorization': wx.getStorageSync('token')
},
success: resolve,
fail: reject
})
})
}

2. 图片处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 图片压缩
wx.compressImage({
src: tempFilePath,
quality: 80,
success(res) {
console.log(res.tempFilePath)
}
})

// 图片上传
wx.uploadFile({
url: 'https://api.example.com/upload',
filePath: tempFilePath,
name: 'file',
success(res) {
console.log(res.data)
}
})

3. 页面返回刷新

1
2
3
4
5
6
7
8
9
10
11
12
13
// 页面A
wx.navigateTo({
url: '/pages/pageB/pageB',
events: {
refreshData: (data) => {
this.loadData()
}
}
})

// 页面B
const eventChannel = this.getOpenerEventChannel()
eventChannel.emit('refreshData', { data: 'refresh' })

拓展阅读