微信小程序 笔记
简介
为什么是微信小程序 ?
1. 微信有海量用户,而且粘性很高,在微信里开发产品更容易触达用户;
2. 推广 app 或公众号的成本太高。
3. 开发适配成本低。
4. 容易⼩规模试错,然后快速迭代。
5. 跨平台。
准备环境
注册账号
建议使用全新的邮箱,没有注册过其他小程序或者公众号的。
访问注册页面,耐⼼完成注册即可。
获取 APPID
由于后期调⽤微信⼩程序的接⼝等功能,需要索取开发者的⼩程序中的 APPID ,所以在注册成功后,可登录,然后获取APPID。
开发工具
微信⼩程序⾃带开发者⼯具,集成开发 预览 调试 发布 于一身的 完整环境。
但是由于编码的体验不算好,因此 建议使⽤ vs code + 微信小程序编辑工具 来实现编码
vs code 负责敲代码, 微信编辑工具 负责预览
小程序结构目录
⼩程序框架的⽬标是通过尽可能简单、⾼效的⽅式让开发者可以在微信中开发具有原⽣APP体验的服
务。
⼩程序框架提供了自己的视图层描述语⾔ WXML 和 WXSS ,以及 JavaScript ,并在视图层与逻
辑层间提供了数据传输和事件系统,让开发者能够专注于数据与逻辑。
小程序文件结构和传统web对比
| 结构 | 传统web | 微信小程序 |
|---|
| 结构 | HTML | WXML |
| 样式 | CSS | WXSS |
| 逻辑 | Javascript | Javascript |
| 配置 | 无 | JSON |
通过以上对⽐得出,传统web 是三层结构。⽽微信⼩程序 是四层结构,多了⼀层 配置.json
基本的项目目录
pages
index
index.js
index.json
index.wxml
index.wxss
logs
...
utils
styles
components
lib
request
app.js
app.json
app.wxss
project.config.json
sitemap.json
基本语法
数据绑定
普通写法
<view>{{ message }}</view>
Page({
data: {
message: 'Hello World'
}
})
组件属性
<view id="{{id}}"></view>
Page({
data: {
id: 1,
}
})
.bool 类型
不要直接写 checked=false,其计算结果是⼀个字符串
<checkbox checked="{{false}}"> </checkbox>
运算
三元运算
<view hidden="{{flag ? true : false}}"> Hidden </view>
算数运算
<view> {{a + b}} + {{c}} + d </view>
Page({
data: {
a: 1,
b: 2,
c: 3
}
})
逻辑判断
<view wx:if="{{length > 5}}"> </view>
字符串运算
<view>{{"hello" + name}}</view>
Page({
data:{
name: 'MINA'
}
注意
花括号和引号之间如果有空格,将最终被解析成为字符串
列表渲染
wx:for
项的变量名默认为 item wx:for-item 可以指定数组当前元素的变量名
下标变量名默认为 index wx:for-index 可以指定数组当前下标的变量名
wx:key ⽤来提⾼数组渲染的性能
wx:key 绑定的值 有如下选择
1. string 类型,表⽰ 循环项中的唯⼀属性 如
list:[{id:0,name:"炒饭"},{id:1,name:"炒面"}]
wx:key="id"
2. 保留字 *this ,它的意思是 item 本⾝ ,*this 代表的必须是 唯⼀的字符串和数组。
list:[1,2,3,4,5]
wx:key="*this"
<view wx:for="{{array}}" wx:key="id">
{{index}}: {{item.message}}
</view>
Page({
data: {
array: [
{
id:0,
message: 'foo',
},
{
id:1,
message: 'bar'
}
]
}
})
block
渲染⼀个包含多节点的结构块 block最终不会变成真正的dom元素
<block wx:for="{{[1, 2, 3]}}" wx:key="*this" >
<view> {{index}}: </view>
<view> {{item}} </view>
</block>
条件渲染
wx:if
在框架中,使⽤ wx:if="{{condition}}" 来判断是否需要渲染该代码块:
<view wx:if="{{false}}">1</view>
<view wx:elif="{{true}}">2</view>
<view wx:else>3</view>
hidden
<view hidden="{{condition}}"> True </view>
类似 wx:if
频繁切换 ⽤ hidden
不常使⽤ ⽤ wx:if
<!-- 注意 hidden与block一起使用是没有效果的 例如:-->
<block hidden="{{true}}">1</block>
<block hidden="{{false}}">2</block>
小程序事件的绑定
⼩程序中绑定事件,通过bind关键字来实现。如 bindtap bindinput bindchange 等
不同的组件支持不同的事件,具体看组件的说明即可。
<!-- wxml -->
<input bindinput="handleInput" />
<!-- page -->
Page({
handleInput: function(e) {
console.log(e);
console.log("值被改变了");
}
)
1. 绑定事件时不能带参数 不能带括号 以下为错误写法
<input bindinput="handleInput(100)" />
2. 事件传值 通过标签自定义属性的⽅式 和 value
<input bindinput="handleInput" data-item="100" />
3. 事件触发时获取数据
handleInput: function(e) {
console.log(e.currentTarget.dataset)
console.log(e.detail.value);
}
样式 WXSS
WXSS( WeiXin Style Sheets )是⼀套样式语⾔,⽤于描述 WXML 的组件样式。
与 CSS 相⽐,WXSS 扩展的特性有:
1. 响应式⻓度单位
2. 样式导⼊
尺寸单位
rpx (responsive pixel): 可以根据屏幕宽度进行自适应。规定屏幕宽为 750rpx 。如在iPhone6 上,屏幕宽度为 375px ,共有750个物理像素,则 750rpx = 375px = 750物理像素 , 1rpx = 0.5px = 1物理像素。
建议: 开发微信⼩程序时设计师可以 iPhone6 作为视觉稿的标准
使用步骤:
1. 确定设计稿宽度 pageWidth
2. 计算⽐例 750rpx = pageWidth px ,因此 1px=750rpx/pageWidth 。
3. 在less⽂件中,只要把设计稿中的 px => 750/pageWidth rpx 即可。
| 设备 | rpx换算px(屏幕宽度/750) | px换算rpx(750/屏幕宽度) |
|---|
| iPhone5 | 1rpx = 0.42px | 1px = 2.34rpx |
| iPhone6 | 1rpx = 0.5px | 1px = 2rpx |
| iPhone6 Plus | 1rpx = 0.552px | 1px = 1.81rpx |
样式导入
wxss中直接就⽀持,样式导⼊功能。
也可以和 less中的导⼊混⽤。
使⽤ @import 语句可以导⼊外联样式表,只⽀持相对路径。
/** 示例代码:*/
/** common.wxss **/
.small-p {
padding: 5px;
}
@import "common.wxss";
.middle-p {
padding:15px;
}
选择器
特别需要注意的是 ⼩程序 不⽀持通配符 * 因此以下代码无效!
*{
margin:0;
padding:0;
box-sizing:border-box;
}
目前支持的选择器有:
| 选择器 | 样例 | 样例描述 |
|---|
| .class | .intro | 选择所有拥有 class=intro 的组件 |
| #id | #firstname | 选择拥有 id=firstname 的组件 |
| element | view | 选择所有 view 组件 |
| element, element | view, checkbox | 选择所有⽂档的 view 组件和所有的 checkbox 组件 |
| nth-child(n) | view:nth-child(n) | 选择某个索引的标签 |
| ::after | view::after | 在 view 组件后边插⼊内容 |
| ::before | view::before | 在 view 组件前边插⼊内容 |
常见组件
view
代替 原来的 div 标签
<view hover-class="h-class">
点击我试试
</view>
text
1. ⽂本标签
2. 只能嵌套text
3. ⻓按⽂字可以复制(只有该标签有这个功能)
4. 可以对空格 回⻋ 进⾏编码
| 属性名 | 类型 | 默认值 | 说明 |
|---|
| selectable | Boolean | false | 文本是否可选 |
| decode | Boolean | false | 是否解码 |
<text selectable="{{false}}" decode="{{false}}">
普 通
</text>
image
1. 图⽚标签,image组件默认宽度320px、⾼度240px
2. ⽀持懒加载
| 属性名 | 类型 | 默认值 | 说明 |
|---|
| src | String | | 图片资源地址 |
| mode | String | 'scaleToFill' | 图片裁剪、缩放的模式 |
| lazy-load | Boolean | false | 图片懒加载 |
mode 有效值:
mode 有 13 种模式,其中 4 种是缩放模式,9种是裁剪模式。
| 模式 | 值 | 说明 |
|---|
| 缩放 | scaleToFill | 不保持纵横比缩放图⽚,使图⽚的宽⾼完全拉伸⾄填满 image 元素 |
| 缩放 | aspectFit | 保持纵横比缩放图⽚,使图⽚的⻓边能完全显⽰出来。 |
| 缩放 | aspectFill | 保持纵横比缩放图⽚,只保证图⽚的短边能完全显⽰出来。 |
| 缩放 | widthFix | 宽度不变,⾼度⾃动变化,保持原图宽⾼⽐不变 |
| 裁剪 | top | 不缩放图⽚,只显⽰图⽚的顶部区域 |
| 裁剪 | bottom | 不缩放图⽚,只显⽰图⽚的底部区域 |
| 裁剪 | center | 不缩放图⽚,只显⽰图⽚的中间区域 |
| 裁剪 | left | 不缩放图⽚,只显⽰图⽚的左边区域 |
| 裁剪 | right | 不缩放图⽚,只显⽰图⽚的右边区域 |
| 裁剪 | top left | 不缩放图⽚,只显⽰图⽚的左上边区域 |
| 裁剪 | top right | 不缩放图⽚,只显⽰图⽚的右上边区域 |
| 裁剪 | bottom left | 不缩放图⽚,只显⽰图⽚的左下边区域 |
| 裁剪 | bottom right | 不缩放图⽚,只显⽰图⽚的右下边区域 |
自定义组件
类似vue或者react中的自定义组件
⼩程序允许我们使用自定义组件的⽅式来构建⻚⾯。
创建自定义组件
类似于页面,一个自定义组件由 json wxml wxss js 4个文件组成
可以在微信开发者⼯具中快速创建组件的文件结构
在⽂件夹内 components/myHeader ,创建组件 名为 myHeader
声明组件
⾸先需要在组件的 json ⽂件中进⾏⾃定义组件声明
myHeader.json
{
"component": true
}
编辑组件
同时,还要在组件的 wxml ⽂件中编写组件模板,在 wxss ⽂件中加⼊组件样式
slot 表⽰插槽,类似vue中的slot
myHeader.wxml
<view class="inner">
{{innerText}}
<slot></slot>
</view>
在组件的 wxss ⽂件中编写样式
注意:在组件wxss中不应使用ID选择器、属性选择器和标签名选择器。
myHeader.wxss
/* 这里的样式只应用于这个自定义组件 */
.inner {
color: red;
}
注册组件
在组件的 js ⽂件中,需要使⽤ Component() 来注册组件,并提供组件的属性定义、内部数据和
⾃定义⽅法
myHeader.js
Component({
properties: {
innerText: {
type: String,
value: 'default value',
}
},
data: {
someData: {}
},
methods: {
customMethod: function(){}
}
})
声明引入自定义组件
⾸先要在⻚⾯的 json ⽂件中进⾏引⽤声明。还要提供对应的组件名和组件路径
index.wxml
{
"usingComponents": {
"my-header":"/components/myHeader/myHeader"
}
}
页面中使用自定义组件
<view>
<my-header inner-text="Some text">
<view>用来替代slot的</view>
</my-header>
</view>
组件-自定义组件传参
1. ⽗组件通过属性的⽅式给⼦组件传递参数 2. ⼦组件通过事件的⽅式向⽗组件传递参数
过程
1. ⽗组件 把数据 {{tabs}} 传递到 ⼦组件的 tabItems 属性中
2. ⽗组件 监听 onMyTab 事件
3. 子组件 触发 bindmytap 中的 mytap 事件
1. 自定义组件触发事件时,需要使⽤ triggerEvent ⽅法,指定 事件名 、 detail 对象
4. ⽗ -> ⼦ 动态传值 this.selectComponent("#tabs")
父组件代码
<tabs tabItems="{{tabs}}" bindmytap="onMyTab"></tabs>
data: {
tabs:[
{name:"体验问题"},
{name:"商品、商家投诉"}
]
},
onMyTab(e){
console.log(e.detail);
},
......
子组件代码
<view class="tabs">
<view class="tab_title" >
<block wx:for="{{tabItems}}" wx:key="{{item}}">
<view bindtap="handleItemActive" data-index="{{index}}">{{item.name}}</view>
</block>
</view>
</view>
Component({
properties: {
tabItems:{
type:Array,
value:[]
}
},
data: {
},
methods: {
handleItemActive(e){
this.triggerEvent('mytap','haha');
}
}
})
小程序生命周期
分为应用生命周期和页面生命周期
应用生命周期
| 属性 | 类型 | 默认值 | 必填 | 说明 |
|---|
| onLaunch | function | | 否 | 监听小程序初始化。 |
| onShow | function | | 否 | 监听小程序启动或切前台。 |
| onHide | function | | 否 | 监听小程序切后台 |
| onError | function | | 否 | 错误监听函数 |
| onPageNotFound | function | | 否 | 页面不存在监听函数 |
页面生命周期
| 属性 | 类型 | 说明 |
|---|
| data | Object | ⻚⾯的初始数据 |
| onLoad | function | ⽣命周期回调—监听⻚⾯加载 |
| onShow | function | ⽣命周期回调—监听⻚⾯显⽰ |
| onReady | function | ⽣命周期回调—监听⻚⾯初次渲染完成 |
| onHide | function | ⽣命周期回调—监听⻚⾯隐藏 |
| onUnload | function | ⽣命周期回调—监听⻚⾯卸载 |
| onPullDownRefresh | function | 监听⽤⼾下拉动作 |
| onReachBottom | function | ⻚⾯上拉触底事件的处理函数 |
| onShareAppMessage | function | ⽤⼾点击右上⻆转发 |
| onPageScroll | function | ⻚⾯滚动触发事件的处理函数 |
| onResize | function | ⻚⾯尺⼨改变时触发,详⻅ 响应显⽰区域变化 |
| onTabItemTap | function | 当前是 tab ⻚时,点击 tab 时触发 |