初识小程序
什么是小程序
小程序是一种轻量级的应用程序,它结合了传统网页和原生应用的优点
小程序的主要特点有:
- 快速启动
- 免安装
- 低内存占用
- 跨平台
网页 vs 小程序
相同点:都遵循 Web 标准
不同点:
- 运行环境不同:网页运行在浏览器中,小程序运行在微信客户端中
- 开发模式不同:网页开发一般用浏览器+编译器,小程序有自己的一套开发模式
- 运行机制不同:网页渲染线程和脚本线程是互斥的,js 脚本会阻塞页面的渲染;小程序渲染线程和脚本线程是两个独立的线程,互不干扰
- API不同:小程序无法调用 DOM 和 BOM,但可以调用微信提供的 API,如定位、扫码、支付等
小程序的开发流程
小程序有自己的一套开发模式:
-
注册小程序账号
-
安装微信开发者工具
-
创建项目,编码,发布上线
注册完成后,就可以登录微信公众平台管理小程序,包括以下几个方面:
- 基本信息:设置小程序的基本信息(名称、头像等)
- 版本管理:管理开发完成的小程序,进行审核和发布
- 成员管理:添加项目成员,协同开发
- 开发管理:获取 APPID,配置服务器域名等
一个邮箱只能发布/上线一个小程序(有一个唯一的APPID)
小程序个人版用户无法调用微信登录、微信支付等功能
编码工作交给微信开发者工具:
- 编译模式:配置多个启动页面,在开发时快速切换
- 编译:编译代码,重新启动模拟器
- 预览/真机调试:将代码打包上传到微信服务器,在手机端扫码查看和调试
- 热重载:保存时,只更新页面变化的部分,而不是重新编译
小程序页面组成
四个文件的名称必须相同,在 app.json 中配置 pages 文件路径会自动生成相应的文件结构
app.js、app.json、app.wxss 分别是项目的入口文件、全局配置文件和全局样式文件
小程序内置组件
view
- 视图容器,是一个块级元素,常用来做页面布局
- 类似 div 标签
scroll-view
- 可滚动视图区域,常用来实现列表滑动效果
- 竖向滚动:给 scroll-view 一个固定高度,同时指定 scroll-y 属性
swiper&swiper-item
- 滑块视图容器(轮播图)
- autoplay自动轮播 interval间隔时间(ms) indicator-dots显示底部指示器
text
- 文本组件,是一个行内元素,用来显示内联文本
- 类似 span 标签
rich-text
- 富文本组件,可以解析html
- nodes要解析的html内容
button
- 按钮组件
- type按钮的样式类型 open-type调用微信提供的各种功能(客服,转发,授权,获取用户信息等)
image
- 图片组件
- image组件默认宽度约是300px,高度为240px
- src图片地址 mode图片裁剪/缩放模式
navigator
- 页面导航组件,用来完成路由跳转
- open-type跳转方式 url跳转路径
- 类似 a 标签
小程序基础语法
事件绑定
语法:bind:xxx="xxx"
<button bind:tap="addCount">+1</button>
单向数据绑定
语法:属性名="{{ xxx }}"
<navigator open-type="switchTab" url="{{ homeUrl }}" class="{{ active ? 'red' : '' }}">首页</navigator>
双向数据绑定
语法:model:value="{{ xxx }}"
<!-- bind:input 去除 Do not have handler in component... 警告 -->
<input model:value="{{ msg }}" bind:input="handlerInp" type="text"/>
小程序目前只支持单一字段、简单类型数据的双向绑定,表达式、路径和对象都不支持。详见 简易双向绑定
列表循环渲染
语法:wx:for="{{ xxx }}"
<view wx:for="{{ students }}" wx:key="id" wx:for-index="i" wx:for-item="stu">
<text>{{ i + 1 }}</text>
<text>{{ stu.name }}</text>
<text>{{ stu.gender }}</text>
<text>{{ stu.age }}</text>
</view>
条件渲染
语法1:wx:if="{{ xxx }}"
底层实现:动态创建/删除节点
<view class="one" wx:if="{{ isShow }}">盒子1</view>
<view class="two" wx:else>盒子2</view>
语法2:hidden="{{ xxx }}"
底层实现:css display显示/隐藏
<view class="three" hidden="{{ isHidden }}">盒子3</view>
配合 block 标签分组,可以控制多个元素的显示与隐藏,并且不会添加任何多余标签
数据更新
小程序响应式数据更新的方式:
- data:定义响应式数据
- setData():响应式数据更新
eg.商品数量加减案例
<view class="cart-box">
<button bind:tap="sub">-</button>
<input type="text" value="{{ count }}"/>
<button bind:tap="add">+</button>
</view>
Page({
data: {
count: 1
},
sub() {
if (this.data.count === 1) return
this.setData({
count: this.data.count - 1
})
},
add() {
this.setData({
count: this.data.count + 1
})
}
})
每个小程序的页面都由全局 Page 函数进行初始化;this 指向当前页面的实例,即 Page 函数传入的对象
页面中的函数不需要定义在 methods 中,直接写在最外层
如果数据是复杂类型的,我们可以:
-
直接覆盖(需要手动保留原有数据)
-
单独修改
eg.复杂类型数据更新
<view class="view-box">
<view>{{ user.username }} - {{ user.age }}</view>
<view>{{ list[0] }} - {{ list[1] }}</view>
</view>
<!-- bind:tap 绑定点击事件 -->
<button type="primary" bind:tap="handlerTap">点击一下</button>
Page({
// 1. data 定义响应式数据
data: {
user: {
username: '张老三',
age: 18
},
list: ['timestamp', +new Date()]
},
handlerTap(e) {
// 2. setData 响应式数据更新
this.setData({
// 方式一覆盖式修改 需要手动保留原有数据
// user: {
// username: this.data.user.username,
// age: this.data.user.age + 1
// },
// list: ['timestamp', +new Date()]
// 方式二 单独修改 不需要手动保留原有数据
['user.age']: this.data.user.age + 1,
['list[1]']: +new Date()
})
}
})
生命周期
关于小程序的生命周期的详细介绍,请参考:微信小程序开发:微信小程序生命周期总结、小程序学习--生命周期
场景值
场景值:一个数值,描述了用户打开小程序的方式,用来分析用户行为,实现精细化营销
常见的场景值示例:
1001
:发现栏小程序主入口1007
:聊天会话中的消息卡片1011
:扫描二维码
// app.js
App({
onLaunch(params) {
console.log('小程序启动了!', params.scene)
},
onShow(params) {
console.log('小程序处于前台状态!', params.scene)
}
}
场景值只能在应用级别的生命周期函数
onLaunch
、onShow
中获取!
页面适配
rpx
是小程序独有的相对长度单位,1rpx = 1/750屏幕宽度
小程序的设计稿标准是 750px,只需要将设计稿上的 px 单位写成 rpx 单位就能完成页面的适配
页面配置
全局配置
在 app.json 中,可以做一些应用的全局配置:
eg.全局配置示例
{
"pages": [
"pages/index/index",
"pages/my/my"
],
"entryPagePath": "pages/index/index",
"window":{
"navigationBarTitleText": "第一个小程序",
"navigationBarTextStyle":"white",
"navigationBarBackgroundColor": "#049388"
},
"tabBar": {
"color": "#333",
"selectedColor": "#FFC64B",
"backgroundColor": "#FFF",
"borderStyle": "black",
"position": "bottom",
"list": [
{
"text": "首页",
"pagePath": "pages/index/index",
"iconPath": "assets/icon/home.png",
"selectedIconPath": "assets/icon/home-active.png"
},
{
"text": "我的",
"pagePath": "pages/my/my",
"iconPath": "assets/icon/my.png",
"selectedIconPath": "assets/icon/my-active.png"
}
]
},
}
@导航栏配置不生效问题
有时明明配置了导航栏,但页面没有任何效果,原因:解决 app.json navigationbar不生效的问题
@静态资源加载问题
总结:页面和样式中使用网络图片,全局配置 tabBar 中只能使用本地图片
局部配置
eg.局部配置示例
// my.json
// 这里的局部配置会覆盖全局配置
{
"usingComponents": {},
"navigationBarTitleText": "我的",
"navigationBarTextStyle": "white",
"navigationBarBackgroundColor": "#333"
}
推荐阅读: