0%

微信小程序-随笔

2020年5月14日

  • MINA在微信小程序开发中MINA代表原生框架

  • 有不少大厂有做框架,不过不建议用,小程序连个dom都操作不了,自己搞了一套wxml+wxss,那些框架也只能带着镣铐跳舞,乍看下去跟基于w3c的vue一样,然而一写起来细节都是坑。

    到头来你既要学vue,还要学小程序,两边都绕不开跑不掉,而且vue还不是w3c的vue,是基于小程序的阉割vue,小程序也不是直接的小程序,是隔了一层畸形vue的小程序,强扭的瓜不甜,何苦来哉。

  • 虽然Vue与小程序很像但不能用Vue来做小程序的

    微信小程序是单向绑定。而vue是双向(微信小程序没有提供v-model的等价指令,仅能通过事件对象读取用户输入)

2020年6月21日

1.微信小程序介绍

微信⼩程序,简称⼩程序,英⽂名 Mini Program ,是⼀种不需要下载安装即可使⽤的应⽤,它实现 了应⽤“触⼿可及”的梦想,⽤⼾扫⼀扫或搜⼀下即可打开应⽤

1.1.为什么是微信小程序

  1. 微信有海量⽤⼾,⽽且粘性很⾼,在微信⾥开发产品更容易触达⽤⼾;
  2. 推广app或公众号的成本太高
  3. 开发适配成本低
  4. 容易小规模试错,然后快速迭代。
  5. 跨平台

1.2.微信小程序历史

  • 2016年1⽉11⽇,微信之⽗张⼩⻰时隔多年的公开亮相,解读了微信的四⼤价值观。张⼩⻰指出, 越来越多产品通过公众号来做,因为这⾥开发、获取⽤⼾和传播成本更低。拆分出来的服务号并没 有提供更好的服务,所以微信内部正在研究新的形态,叫「微信⼩程序」 需要注意的是,之前是叫 做 应⽤号
  • 2016年9⽉21⽇,微信⼩程序正式开启内测。在微信⽣态下,触⼿可及、⽤完即⾛的微信⼩程序引 起⼴泛关注。腾讯云正式上线微信⼩程序解决⽅案,提供⼩程序在云端服务器的技术⽅案。
  • 2017年1⽉9⽇,微信推出的“⼩程序”正式上线。“⼩程序”是⼀种⽆需安装,即可使⽤的⼿ 机“应⽤”。不需要像往常⼀样下载App,⽤⼾在微信中“⽤完即⾛”。

1.3.疯狂的微信小程序

1.微信⽉活已经达到10.82亿。其中55岁以上的⽤⼾也达到6300万

2.信息传达数达到450亿,较去年增⻓18%;视频通话4.1亿次,增⻓100%

3.⼩程序覆盖超过200+⾏业,交易额增⻓超过6倍,服务1000亿+⼈次,创造出了5000亿+的商业价值

1.4.还有其他小程序不容忽视

1.支付宝小程序

2.百度小程序

3.qq小程序

4.今日头条+抖音小程序

1.5.体验

1.5.1.官方微信小程序体验

微信小程序体验

1.5.2.其他优秀的第三方小程序

  • 拼多多
  • 滴滴出行
  • 欢乐斗地主
  • 唯品会
  • …….

2.环境准备

开发微信⼩程序之前,必须要准备好相应的环境

2.1.注册账号

建议使用全新的邮箱,没有注册过其他小程序或者公众号的。注册入口

2.2. 获取APPID

由于后期调⽤微信⼩程序的接⼝等功能,需要索取开发者的⼩程序中的 APPID ,所以在注册成功后, 可登录,然后获取APPID。

登录成功后可看到如下界⾯ 然后复制你的APPID,悄悄的保存起来,不要给别⼈看到

小程序发布流程

![小程序发布流程2]小程序发布流程2.png)

2.3.开发工具

下载地址

开发者工具

微信⼩程序⾃带开发者⼯具,集 开发 预览 调试 发布 于⼀⾝的 完整环境。 但是由于编码的体验不算好,因此 建议使⽤ vscode+ 微信小程序编辑工具 来实现编码 vscode 负责敲代码, 微信编辑工具 负责预览

3.第一个微信小程序

3.1.打开微信开发者工具

注意 第⼀次登录的时候 需要扫码登录

二维码登录

3.2.新建小程序项目

新建项目

3.4.成功

新建项目已2

4.微信开发者工具介绍

详细的使⽤,可以查看官⽹

工具介绍

5.小程序结构目录

小程序框架的⽬标是通过尽可能简单、⾼效的⽅式让开发者可以在微信中开发具有原⽣APP体验的服 务。 ⼩程序框架提供了⾃⼰的视图层描述语⾔ WXML 和 WXSS ,以及 JavaScript ,并在视图层与逻 辑层间提供了数据传输和事件系统,让开发者能够专注于数据与逻辑。

5.1.小程序文件结构和传统Web对比

结构 传统web 微信⼩程序
结构 HTML WXML
样式 CSS WXSS
逻辑 Javascript Javascript
配置 JSON

通过以上对⽐得出,传统web 是三层结构。⽽微信⼩程序 是四层结构,多了⼀层 配置.json

5.2.基本项目目录

基本项目目录

6.⼩程序配置⽂件

⼀个⼩程序应⽤程序会包括最基本的两种配置⽂件。⼀种是全局的 app.json 和 ⻚⾯⾃⼰的 page.json

注意:配置文件中不能出现注释

6.1全局配置app.json

app.json 是当前⼩程序的全局配置,包括了⼩程序的所有⻚⾯路径、界⾯表现、⽹络超时时间、底 部 tab 等。普通快速启动项⽬⾥边的app.json 配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
"pages": [
"pages/index/index",
"pages/logs/logs"
],
"window": {
"backgroundTextStyle": "dark",
"navigationBarBackgroundColor": "#0094ff",
"navigationBarTitleText": "我的应用",
"navigationBarTextStyle": "white",
"enablePullDownRefresh": true,
"backgroundColor": "#0294ff",
"backgroundColorBottom": "#0292ff"
},

"style": "v2",
"sitemapLocation": "sitemap.json"
}

字段的含义:

  1. pages字段⸺⽤于描述当前⼩程序所有⻚⾯路径,这是为了让微信客⼾端知道当前你的⼩程序 ⻚⾯定义在哪个⽬录.
  2. window字段⸺定义⼩程序所有⻚⾯的顶部背景颜⾊,⽂字颜⾊定义等
  3. . 完整的配置信息请参考app.json配置

6.1.1. tabbar

![tabbartabbar.png)

6.2.页面配置page.json

这⾥的 page.json 其实⽤来表⽰⻚⾯⽬录下的page.json 这类和⼩程序⻚⾯相关的配置。 开发者可以独⽴定义每个⻚⾯的⼀些属性,如顶部颜⾊、是否允许下拉刷新等等。 ⻚⾯的配置只能设置 app.json中部分 window配置项的内容,⻚⾯中配置项会覆盖app.jsonwindow中相同的配置项。

属性 类型 默认值 描述
navigationBarBackgroundColor HexColor #000000 导航栏背景颜⾊,如 #000000
navigationBarTextStyle String white 导航栏标题颜⾊,仅⽀持 black/ white
avigationBarTitleText String 导航栏标题⽂字内容
backgroundColor HexColor #ffffff 窗⼝的背景⾊
backgroundTextStyle String dark 下拉 loading 的样式,仅⽀持 dark / light
enablePullDownRefresh Boolean false 是否全局开启下拉刷新。 详⻅ Page.onPullDownRefresh
onReachBottomDistance Number 50 ⻚⾯上拉触底事件触发时距⻚⾯底部距离,单位为px。 详⻅ Page.onReachBottom
disableScroll Boolean false 设置为 true 则⻚⾯整体不能上下滚动;只在⻚⾯配置中有 效,⽆法在app.json 中设置该项

7.模板语法

WXML(WeiXin Markup Language)是框架设计的⼀套标签语⾔,结合基础组件、事件系统,可以构 建出⻚⾯的结构。

7.1.数据绑定

7.1.1普通写法

1
<view> {{ message }} </view>
1
2
3
4
5
Page({
data: {
message: 'Hello MINA!'
}
})

7.1.2. 组件属性

1
<view id="item-{{id}}"> </view>
1
2
3
4
5
Page({
data: {
id: 0
}
})

7.1.3. bool类型

不要直接写 checked=false,其计算结果是⼀个字符串

1
<checkbox checked="{{false}}"> </checkbox>

7.2. 运算

7.2.1. 三元运算

1
<view hidden="{{flag ? true : false}}"> Hidden </view>

7.2.2. 算数运算

1
<view> {{a + b}} + {{c}} + d </view>
1
2
3
4
5
6
7
Page({
data: {
a: 1,
b: 2,
c: 3
}
})

7.2.3. 逻辑判断

1
<view wx:if="{{length > 5}}"> </view>

7.2.4. 字符串运算

1
<view>{{"hello" + name}}</view>
1
2
3
4
5
Page({
data:{
name: 'MINA'
}
})

7.2.5. 注意

花括号和引号之间如果有空格,将最终被解析成为字符串

7.3. 列表渲染

7.3.1. wx:for

项的变量名默认为 item wx:for–item 可以指定数组当前元素的变量名 下标变量名默认为 index wx:for–index 可以指定数组当前下标的变量名 wx:key ⽤来提⾼数组渲染的性能 wx:key 绑定的值 有如下选择

  1. string类型,表⽰ 循环项中的唯⼀属性 如

    1
    2
    list:[{id:0,name:"炒饭"},{id:1,name:"炒面"}]
    wx:key="id"
  2. 保留字 *this ,它的意思是 item 本⾝ ,*this 代表的必须是 唯⼀的字符串和数组。

    1
    2
    list:[1,2,3,4,5]
    wx:key="*this"

代码:

1
2
3
<view wx:for="{{array}}" wx:key="id">
{{index}}: {{item.message}}
</view>
1
2
3
4
5
6
7
8
9
10
11
Page({
data: {
array: [{
id:0,
message: 'foo',
}, {
id:1,
message: 'bar'
}]
}
})

7.3.2. block

渲染⼀个包含多节点的结构块 block最终不会变成真正的dom元素

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

7.4. 条件渲染

7.4.1. wx:if

在框架中,使⽤ wx:if="" 来判断是否需要渲染该代码块:

1
2
3
<view wx:if="{{false}}">1</view>
<view wx:elif="{{true}}">2</view>
<view wx:else>3</view>

7.4.2. hidden

1
<view hidden="{{condition}}"> True </view>

类似wx:if 同Vuejs中的v-ifv-show

频繁切换 ⽤hidden

不常使⽤ ⽤wx:if

8.小程序事件绑定

⼩程序中绑定事件,通过bind关键字来实现。如 bindtap bindinput bindchange 等 不同的组件⽀持不同的事件,具体看组件的说明即可。

8.1. wxml

1
<input bindinput="handleInput" />

8.2.page

1
2
3
4
5
6
7
Page({
// 绑定的事件
handleInput: function(e) {
console.log(e);
console.log("值被改变了");
}
})

8.3. 特别注意

  1. 绑定事件时不能带参数 不能带括号 以下为错误写法

    1
    <input bindinput="handleInput(100)" />
  2. 事件传值 通过标签⾃定义属性的⽅式 和 value

    1
    <input bindinput="handleInput" data-item="100" />
  3. 事件触发时获取数据

    1
    2
    3
    4
    5
    6
    7
     handleInput: function(e) {
    // {item:100}
    console.log(e.currentTarget.dataset)

    // 输入框的值
    console.log(e.detail.value);
    }

9.样式WXSS

WXSS( WeiXin Style Sheets )是⼀套样式语⾔,⽤于描述 WXML 的组件样式。 与 CSS 相⽐,WXSS 扩展的特性有:

  • 响应式⻓度单位 rpx
  • 样式导⼊

9.1. 尺⼨单位

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

设备 rpx换算px (屏幕宽度/750) px换算rpx (750/屏幕宽度)
iPhone5 1rpx = 0.42px 1px = 2.34rpx
Phone6 1rpx = 0.5px 1px = 2rpx
iPhone6 Plus 1rpx = 0.552px 1px = 1.81rpx

建议: 开发微信⼩程序时设计师可以⽤ iPhone6 作为视觉稿的标准。

使⽤步骤:

1.确定设计稿宽度 pageWidth

2.算⽐例 750rpx = pageWidth px ,因此1px=750rpx/pageWidth

3.在less⽂件中,只要把设计稿中的 px => 750/pageWidth rpx 即可。

9.2. 样式导⼊

wxss中直接就⽀持,样式导⼊功能

也可以和 less中的导⼊混⽤

使⽤ @import 语句可以导⼊外联样式表,只⽀持相对路径。

⽰例代码:

1
2
3
4
/** common.wxss **/
.small-p {
padding:5px;
}
1
2
3
4
5
/** app.wxss **/
@import "common.wxss";
.middle-p {
padding:15px;
}

9.3. 选择器

特别需要注意的是 ⼩程序 不⽀持通配符* 因此以下代码⽆效!

1
2
3
4
5
*{
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 组件前边插⼊内容

9.4. ⼩程序中使⽤less

原⽣⼩程序不⽀持 less ,其他基于⼩程序的框架⼤体都⽀持,如 wepympvuetaro等。 但是仅仅因为⼀个less功能,⽽去引⼊⼀个框架,肯定是不可取的。因此可以⽤以下⽅式来实现

1.编辑器是 vscode

2.安装插件 easy less

less插件

3.. 在vscode的设置中加⼊如下,配置

1
2
3
"less.compile": {
"outExt": ".wxss"
}
  1. 在要编写样式的地⽅,新建 less⽂件,如index.less,然后正常编辑即可。

10.常见组件

⼩程序中常⽤的布局组件

view,text,rich--text,button,image,navigator,icon,swiper,radio,checkbox。 等

10.1. view

代替 原来的 div标签

1
2
3
 <view hover-class="h-class">
点击我试试
</view>

10.2. text

1.⽂本标签

2.⽂本标签

3.⻓按⽂字可以复制(只有该标签有这个功能)

4.可以对空格 回⻋ 进⾏编码

属性名 类型 默认值 说明
selectable Boolean false ⽂本是否可选
decode Boolean false 是否解码
1
2
3
<text selectable="{{false}}" decode="{{false}}">
普&nbsp;通
</text>

10.3.images

1.图⽚标签,image组件默认宽度320px、⾼度240px

2.⽀持懒加载

属性名 类型 默认值 说明
src String 图⽚资源地址
mode String ‘scaleToFill’ 图⽚裁剪、缩放的模式
lazy-load Boolean false 图⽚懒加载

mode 有效值:

mode 有 13 种模式,其中 4 种是缩放模式,9种是裁剪模式。

说明
scaleToFill 缩放模式,不保持纵横比缩放图片,使图片的宽高完全拉伸至填满 image 元素
aspectFit 缩放模式,保持纵横比缩放图片,使图片的长边能完全显示出来。也就是说,可以完整地将图片显示出来。
aspectFill 缩放模式,保持纵横比缩放图片,只保证图片的短边能完全显示出来。也就是说,图片通常只在水平或垂直方向是完整的,另一个方向将会发生截取。
widthFix 缩放模式,宽度不变,高度自动变化,保持原图宽高比不变
heightFix 缩放模式,高度不变,宽度自动变化,保持原图宽高比不变
top 裁剪模式,不缩放图片,只显示图片的顶部区域
bottom 裁剪模式,不缩放图片,只显示图片的底部区域
center 裁剪模式,不缩放图片,只显示图片的中间区域
left 裁剪模式,不缩放图片,只显示图片的左边区域
right 裁剪模式,不缩放图片,只显示图片的右边区域
top left 裁剪模式,不缩放图片,只显示图片的左上边区域
top right 裁剪模式,不缩放图片,只显示图片的右上边区域
bottom left 裁剪模式,不缩放图片,只显示图片的左下边区域
bottom right 裁剪模式,不缩放图片,只显示图片的右下边区域

10.4. swiper

微信内置轮播图组件

![swiper]swapper.png)

默认宽度 100% ⾼度 150px

属性 类型 默认值 必填 说明
indicator-dots boolean false 是否显示面板指示点
indicator-color color rgba(0, 0, 0, .3) 指示点颜色
indicator-active-color color #000000 当前选中的指示点颜色
autoplay boolean false 是否自动切换
current number 0 当前所在滑块的 index
interval number 5000 自动切换时间间隔
duration number 500 滑动动画时长
circular boolean false 是否采用衔接/循环滑动
vertical boolean false 滑动方向是否为纵向
previous-margin string “0px” 前边距,可用于露出前一项的一小部分,接受 px 和 rpx 值
next-margin string “0px” 后边距,可用于露出后一项的一小部分,接受 px 和 rpx 值
display-multiple-items number 1 同时显示的滑块数量
skip-hidden-item-layout boolean false 是否跳过未显示的滑块布局,设为 true 可优化复杂情况下的滑动性能,但会丢失隐藏状态滑块的布局信息
easing-function string “default” 指定 swiper 切换缓动动画类型
bindchange eventhandle current 改变时会触发 change 事件,event.detail = {current, source}
bindtransition eventhandle swiper-item 的位置发生改变时会触发 transition 事件,event.detail = {dx: dx, dy: dy}
bindanimationfinish eventhandle 动画结束时会触发 animationfinish 事件,event.detail 同上

10.4.1. swiper

滑块视图容器

10.4.2. swiper-item

滑块

默认宽度和⾼度都是100%

10.5. navigator

导航组件 类似超链接标签

属性名 类型 默认值 说明
target String self 在哪个⽬标上发⽣跳转,默认当前⼩程序,可选值 self/miniProgram
url String 当前⼩程序内的跳转链接
opentype String navigate 跳转⽅式

open-type 有效值:

说明
navigate 保留当前页面,跳转到应用内的某个页面,但是不能跳转到tabbar页面
redirect 关闭当前页面,跳转到应用内的某个页面,但是不允许跳转到tabbar页面
switchTab 跳转到tabbar页面,并关闭其他所有非tabbar页面
reLaunch 关闭所有页面,打开应用内的某个页面
navigateBack 关闭当前页面,返回上一页面或多级页面,可通过getCurrentPages()获取当前也买你栈,决定需要返回几层
exit 退出小程序,target="miniProgram"时生效

10.6. rich-text

富文本标签

可以将字符串解析成 对应标签,类似 vue中 v--html 功能

富文本标签

代码:

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
// 1   index.wxml 加载 节点数组
<rich-text nodes="{{nodes}}" bindtap="tap"></rich-text>
// 2 加载 字符串
<rich-text nodes='<img
src="https://developers.weixin.qq.com/miniprogram/assets/images/head_global_z_@all.p
ng" alt="">'></rich-text>

// index.js

Page({
data: {
nodes: [{
name: 'div',
attrs: {
class: 'div_class',
style: 'line-height: 60px; color: red;'
},
children: [{
type: 'text',
text: 'Hello&nbsp;World!'
}]
}]
},
tap() {
console.log('tap')
}
})

10.6.1. nodes属性

nodes属性⽀持 字符串标签节点数组

属性 说明 类型 必填 备注
name 标签名 string ⽀持部分受信任的 HTML 节点
attrs 属性 object ⽀持部分受信任的属性,遵循 Pascal 命名法
children ⼦节点列表 array 结构和 nodes ⼀致

⽂本节点:type = text

属性 说明 类型 必填 备注
text ⽂本 string ⽀持entities
  • nodes不推荐使⽤ String 类型,性能会有所下降。
  • rich--text组件内屏蔽所有节点的事件。
  • attrs 属性不⽀持 id ,⽀持 class 。
  • name 属性⼤⼩写不敏感。
  • 如果使⽤了不受信任的 HTML 节点,该节点及其所有⼦节点将会被移除。
  • img标签仅⽀持⽹络图⽚。

10.7. button

button

1
2
3
4
5
6
7
<button
type="default"
size="{{defaultSize}}"
loading="{{loading}}"
plain="{{plain}}"
>
default
属性 类型 默认值 必填 说明
size string default 按钮的大小
type string default 按钮的样式类型
plain boolean false 按钮是否镂空,背景色透明
disabled boolean false 是否禁用
loading boolean false 名称前是否带 loading 图标
form-type string 用于 form 组件,点击分别会触发 form 组件的 submit/reset 事件
open-type string 微信开放能力
hover-class string button-hover 指定按钮按下去的样式类。当 hover-class="none" 时,没有点击态效果
hover-stop-propagation boolean false 指定是否阻止本节点的祖先节点出现点击态
hover-start-time number 20 按住后多久出现点击态,单位毫秒
hover-stay-time number 70 手指松开后点击态保留时间,单位毫秒
lang string en 指定返回用户信息的语言,zh_CN 简体中文,zh_TW 繁体中文,en 英文。
session-from string 会话来源,open-type=”contact”时有效
send-message-title string 当前标题 会话内消息卡片标题,open-type=”contact”时有效
send-message-path string 当前分享路径 会话内消息卡片点击跳转小程序路径,open-type=”contact”时有效
send-message-img string 截图 会话内消息卡片图片,open-type=”contact”时有效
app-parameter string 打开 APP 时,向 APP 传递的参数,open-type=launchApp时有效
show-message-card boolean false 是否显示会话内消息卡片,设置此参数为 true,用户进入客服会话会在右下角显示”可能要发送的小程序”提示,用户点击后可以快速发送小程序消息,open-type=”contact”时有效
bindgetuserinfo eventhandle 用户点击该按钮时,会返回获取到的用户信息,回调的detail数据与wx.getUserInfo返回的一致,open-type=”getUserInfo”时有效
bindcontact eventhandle 客服消息回调,open-type=”contact”时有效
bindgetphonenumber eventhandle 获取用户手机号回调,open-type=getPhoneNumber时有效
binderror eventhandle 当使用开放能力时,发生错误的回调,open-type=launchApp时有效
bindopensetting eventhandle 在打开授权设置页后回调,open-type=openSetting时有效
bindlaunchapp eventhandle 打开 APP 成功的回调,open-type=launchApp时有效

size 的合法值

说明
default 默认大小
mini 小尺寸

type 的合法值

说明
primary 绿色
default 白色
warn 红色

form-type 的合法值

说明
submit 提交表单
reset 重置表单

open-type 的合法值

说明
contact 打开客服会话,如果用户在会话中点击消息卡片后返回小程序,可以从 bindcontact 回调中获得具体信息,具体说明
share 触发用户转发,使用前建议先阅读使用指引
getPhoneNumber 获取用户手机号,可以从bindgetphonenumber回调中获取到用户信息,具体说明
getUserInfo 获取用户信息,可以从bindgetuserinfo回调中获取到用户信息
launchApp 打开APP,可以通过app-parameter属性设定向APP传的参数具体说明
openSetting 打开授权设置页
feedback 打开“意见反馈”页面,用户可提交反馈内容并上传日志,开发者可以登录小程序管理后台后进入左侧菜单“客服反馈”页面获取到反馈内容

lang 的合法值

说明
en 英文
zh_CN 简体中文
zh_TW 繁体中文

open-type 的 contact的实现流程

  1. 将⼩程序 的 appid 由测试号改为 ⾃⼰的 appid
  2. 登录微信⼩程序官⽹,添加 客服 – 微信
  3. 为了⽅便演⽰,⽼师⾃⼰准备了两个账号
    • 普通⽤⼾ A
    • 客服-微信 B
  4. 就是⼲!

10.8.icon

图标。组件属性的长度单位默认为px,2.4.0起支持传入单位(rpx/px)。

属性 类型 默认值 必填 说明
type string icon的类型,有效值:success, success_no_circle, info, warn, waiting, cancel, download, search, clear
size number/string 23 icon的大小
color string icon的颜色,同css的color

icon

示例代码

js

1
2
3
4
5
6
7
8
9
10
11
Page({
data: {
iconSize: [20, 30, 40, 50, 60, 70],
iconColor: [
'red', 'orange', 'yellow', 'green', 'rgb(0,255,255)', 'blue', 'purple'
],
iconType: [
'success', 'success_no_circle', 'info', 'warn', 'waiting', 'cancel', 'download', 'search', 'clear'
]
}
})

wxml

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
109
110
<view class="container">
<view class="icon-box">
<icon class="icon-box-img" type="success" size="93"></icon>
<view class="icon-box-ctn">
<view class="icon-box-title">成功</view>
<view class="icon-box-desc">用于表示操作顺利完成</view>
</view>
</view>
<view class="icon-box">
<icon class="icon-box-img" type="info" size="93"></icon>
<view class="icon-box-ctn">
<view class="icon-box-title">提示</view>
<view class="icon-box-desc">用于表示信息提示;也常用于缺乏条件的操作拦截,提示用户所需信息</view>
</view>
</view>
<view class="icon-box">
<icon class="icon-box-img" type="warn" size="93" color="#C9C9C9"></icon>
<view class="icon-box-ctn">
<view class="icon-box-title">普通警告</view>
<view class="icon-box-desc">用于表示操作后将引起一定后果的情况;也用于表示由于系统原因而造成的负向结果</view>
</view>
</view>
<view class="icon-box">
<icon class="icon-box-img" type="warn" size="93"></icon>
<view class="icon-box-ctn">
<view class="icon-box-title">强烈警告</view>
<view class="icon-box-desc">用于表示由于用户原因造成的负向结果;也用于表示操作后将引起不可挽回的严重后果的情况</view>
</view>
</view>
<view class="icon-box">
<icon class="icon-box-img" type="waiting" size="93"></icon>
<view class="icon-box-ctn">
<view class="icon-box-title">等待</view>
<view class="icon-box-desc">用于表示等待,告知用户结果需等待</view>
</view>
</view>
<view class="icon-box">
<view class="icon-small-wrp">
<icon class="icon-small" type="success_no_circle" size="23"></icon>
</view>
<view class="icon-box-ctn">
<view class="icon-box-title">多选控件图标_已选择</view>
<view class="icon-box-desc">用于多选控件中,表示已选择该项目</view>
</view>
</view>
<view class="icon-box">
<view class="icon-small-wrp">
<icon class="icon-small" type="circle" size="23"></icon>
</view>
<view class="icon-box-ctn">
<view class="icon-box-title">多选控件图标_未选择</view>
<view class="icon-box-desc">用于多选控件中,表示该项目可被选择,但还未选择</view>
</view>
</view>
<view class="icon-box">
<view class="icon-small-wrp">
<icon class="icon-small" type="warn" size="23"></icon>
</view>
<view class="icon-box-ctn">
<view class="icon-box-title">错误提示</view>
<view class="icon-box-desc">用于在表单中表示出现错误</view>
</view>
</view>
<view class="icon-box">
<view class="icon-small-wrp">
<icon class="icon-small" type="success" size="23"></icon>
</view>
<view class="icon-box-ctn">
<view class="icon-box-title">单选控件图标_已选择</view>
<view class="icon-box-desc">用于单选控件中,表示已选择该项目</view>
</view>
</view>
<view class="icon-box">
<view class="icon-small-wrp">
<icon class="icon-small" type="download" size="23"></icon>
</view>
<view class="icon-box-ctn">
<view class="icon-box-title">下载</view>
<view class="icon-box-desc">用于表示可下载</view>
</view>
</view>
<view class="icon-box">
<view class="icon-small-wrp">
<icon class="icon-small" type="info_circle" size="23"></icon>
</view>
<view class="icon-box-ctn">
<view class="icon-box-title">提示</view>
<view class="icon-box-desc">用于在表单中表示有信息提示</view>
</view>
</view>
<view class="icon-box">
<view class="icon-small-wrp">
<icon class="icon-small" type="cancel" size="23"></icon>
</view>
<view class="icon-box-ctn">
<view class="icon-box-title">停止或关闭</view>
<view class="icon-box-desc">用于在表单中,表示关闭或停止</view>
</view>
</view>
<view class="icon-box">
<view class="icon-small-wrp">
<icon class="icon-small" type="search" size="14"></icon>
</view>
<view class="icon-box-ctn">
<view class="icon-box-title">搜索</view>
<view class="icon-box-desc">用于搜索控件中,表示可搜索</view>
</view>
</view>

</view>

10.9. radio

可以通过 color属性来修改颜色

redio

需要搭配 radio-group ⼀起使⽤

10.10. checkbox

可以通过 color属性来修改颜色

checkbox

需要搭配 checkbox-group ⼀起使⽤

11.自定义组件

类似vue或者react中的自定义组件

⼩程序允许我们使⽤⾃定义组件的⽅式来构建⻚⾯。

11.1. 创建⾃定义组件

类似于页面,一个自定义组件由json wxml wxss js 4个文件组成

可以在微信开发者⼯具中快速创建组件的⽂件结构

自定义组件

在⽂件夹内 components/myHeader ,创建组件 名为 myHeader

自定义组件2

11.1.1. 声明组件

⾸先需要在组件的 json ⽂件中进⾏⾃定义组件声明

myHeader.json

1
2
3
{
"component": true
}

11.1.2. 编辑组件

同时,还要在组件的 wxml⽂件中编写组件模板,在 wxss⽂件中加⼊组件样式 slot表⽰插槽,类似vue中的slot

myHeader.wxml

1
2
3
4
5
<!-- 这是自定义组件的内部WXML结构 -->
<view class="inner">
{{innerText}}
<slot></slot>
</view>

在组件的 wxss ⽂件中编写样式

注意:在组件wxss中不应使用ID选择器、属性选择器和标签名选择器。

myHeader.wxss

1
2
3
4
/* 这里的样式只应用于这个自定义组件 */
.inner {
color: red;
}

11.1.3. 注册组件

在组件的 js ⽂件中,需要使⽤Component()来注册组件,并提供组件的属性定义、内部数据和 ⾃定义⽅法

myHeader.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Component({
properties: {
// 这里定义了innerText属性,属性值可以在组件使用时指定
innerText: {
// 期望要的数据是 string类型
type: String,
value: 'default value',
}
},
data: {
// 这里是一些组件内部数据
someData: {}
},
methods: {
// 这里是一个自定义方法
customMethod: function(){}
}
})

11.2.声明引入自定义组件

⾸先要在⻚⾯的 json ⽂件中进⾏引⽤声明。还要提供对应的组件名和组件路径

index.wxml

1
2
3
4
5
6
7
{
// 引用声明
"usingComponents": {
// 要使用的组件的名称 // 组件的路径
"my-header":"/components/myHeader/myHeader"
}
}

11.3. ⻚⾯中使⽤⾃定义组件

1
2
3
4
5
6
<view>
<!-- 以下是对一个自定义组件的引用 -->
<my-header inner-text="Some text">
<view>用来替代slot的</view>
</my-header>
</view>

11.4. 其他属性

11.5. 定义段与⽰例⽅法

Component 构造器可⽤于定义组件,调⽤ Component 构造器时可以指定组件的属性、数据、⽅法 等。

定义段 类型 是 否 必 填 描述
properties Object Map 组件的对外属性,是属性名到属性设置的映射表,参⻅下⽂
data Object 组件的内部数据,和 properties ⼀同⽤于组件的模板渲 染
observers Object 组件数据字段监听器,⽤于监听 properties 和 data 的变 化,参⻅ 数据监听器
methods Object 组件的⽅法,包括事件响应函数和任意的⾃定义⽅法,关于 事件响应函数的使⽤,参⻅ 组件事件
created Function 组件⽣命周期函数,在组件实例刚刚被创建时执⾏,注意此 时不能调⽤ setData ,参⻅ 组件⽣命周期
attached Function 组件⽣命周期函数,在组件实例进⼊⻚⾯节点树时执⾏,参 ⻅ 组件⽣命周期
ready Function 组件生命周期含糊,在组件布局完毕后执行,参见组件生命周期
moved Function 组件⽣命周期函数,在组件实例被移动到节点树另⼀个位置 时执⾏,参⻅ 组件⽣命周期
detached Function 组件⽣命周期函数,在组件实例被从⻚⾯节点树移除时执 ⾏,参⻅ 组件⽣命周期

11.6. 组件-⾃定义组件传参

  1. ⽗组件通过属性的⽅式给⼦组件传递参数

  2. ⼦组件通过事件的⽅式向⽗组件传递参数

11.6.1. 过程

  1. ⽗组件 把数据传递到 ⼦组件的 tabItems属性中

  2. ⽗组件 监听 onMyTab事件

  3. ⼦组件 触发 bindmytap中的 mytap事件

    1. ⾃定义组件触发事件时,需要使⽤ triggerEvent⽅法,指定 事件名 、 detail对象
  4. ⽗ -> ⼦ 动态传值 this.selectComponent(“#tabs”);

⽗组件代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// page.wxml
<tabs tabItems="{{tabs}}" bindmytap="onMyTab" >
内容-这里可以放插槽
</tabs>
// page.js
data: {
tabs:[
{name:"体验问题"},
{name:"商品、商家投诉"}
]
},
onMyTab(e){
console.log(e.detail);
},

⼦组件代码

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
// com.wxml
<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 class="tab_content">
<slot></slot>
</view>
</view>
// com.js
Component({
properties: {
tabItems:{
type:Array,
value:[]
}
},
/**
* 组件的初始数据
*/
data: {
},
/**
* 组件的方法列表
*/
methods: {
handleItemActive(e){
this.triggerEvent('mytap','haha');
}
}
})

11.7. ⼩结

  1. 标签名 是 中划线的⽅式
  2. 属性的⽅式 也是要中划线的⽅式
  3. . 其他情况可以使⽤驼峰命名
    1. 组件的⽂件名如 myHeader.js 的等
    2. .组件内的要接收的属性名 如 innerText
  4. 更多….

12.⼩程序⽣命周期

分为应⽤⽣命周期⻚⾯⽣命周期

关于小程序前后台的定义和小程序的运行机制,请参考官方文档运行机制章节。

12.1. 应⽤⽣命周期

属性 类型 默认值 必填 说明
onLaunch function 生命周期回调——监听小程序初始化。
onShow function 生命周期回调——监听小程序启动或切前台。
onHide function 生命周期回调——监听小程序切后台。
onError function 错误监听函数。
onPageNotFound function 页面不存在监听函数。
onUnhandledRejection function 未处理的 Promise 拒绝事件监听函数。
onThemeChange function 监听系统主题变化

12.2. ⻚⾯⽣命周期

属性 类型 说明
data Object 页面的初始数据
onLoad function 生命周期回调—监听页面加载
onShow function 生命周期回调—监听页面显示
onReady function 生命周期回调—监听页面初次渲染完成
onHide function 生命周期回调—监听页面隐藏
onUnload function 生命周期回调—监听页面卸载
onPullDownRefresh function 监听用户下拉动作
onReachBottom function 页面上拉触底事件的处理函数
onShareAppMessage function 用户点击右上角转发
onAddToFavorites function 用户点击右上角收藏
onPageScroll function 页面滚动触发事件的处理函数
onResize function 页面尺寸改变时触发,详见 响应显示区域变化
onTabItemTap function 当前是 tab 页时,点击 tab 时触发

12.3. ⻚⾯⽣命周期图解

生命周期详解

13.项目实战

13.1项目技术选项

小程序第三方封装的插件

  • 腾讯 wepy 类似vue
  • 美团 mpvue 类似vue
  • 京东 taro 类似react
  • 滴滴 chamelcon
  • uni-app 类似vue
  • 原生框架 MINA

目前微信小程序还处于快速迭代不稳定期间,实际开发中不建议使用第三方框架

13.2.接口文档

13.3.帮助文档

  1. 小程序开发文档
  2. mdn
  3. 阿里巴巴字体 iconfont

填入自己的appid

13.4.搭建项目目录解构

⽬录名 作⽤
styles 存放公共样式
components 存放组件
lib 存放第三⽅库
utils ⾃⼰的帮助库
request ⾃⼰的接⼝帮助库

13.5.搭建项目页面

页面名称 名称
首页 index
分类页面 category
商品列表页面 goods_list
商品详情页面 goods_detail
购物车页面 cart
收藏页面 collect
订单页面 oreder
搜索页面 search
个人中心页面 user
意见反馈页面 feedback
登录页面 login
授权页面 auth
结算页面 pay

13.6.引入字体图片

进入阿里巴巴iconfont—>搜索自己想要的图片—>加入到购物车—>添加到项目/新建项目—>选择Font class类型—>生成在线连接—>copy样式文件—>保存到本地—>页面使用

![iconfont]iconfont.png)

使用代码

1
2
3
<view >首页
<text class="iconfont icon-fukuantongzhi"></text>
</view>

13.7.项目开发

13.7.1首页开发

13.7.1.1.轮播图

index.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//Page Object
Page({
data: {
//轮播图数组
swiperList:[]
},
//页面开始加载 就会触发
onLoad: function(options){
//1.发送异步请求获取轮播图数据
wx.request({
url: 'https://api-hmugo-web.itheima.net/api/public/v1/home/swiperdata',
success:(res)=>{
console.log(res)
this.setData({
swiperList:res.data.message
})


}
})
}

为了避免出现回调地狱的情况,我么使用Proimes对request进行一层封装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// request/index,js
export const request=(params)=>{
return new Promise((resolve,reject)=>{
wx.request({
...params,
success:(res)=>{
//成功返回时
resolve(res)
},
fail:(err)=>{
//失败返回
reject(err)
}
});
})
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/peges/index/index.js
// 1 引入发送请求的方法 方法一定要路径补全
import {request} from "../../request/index.js";
Page({
data: {
//轮播图数组
swiperList:[],
//导航数组
catesList:[]
},
//页面开始加载 就会触发
onLoad: function(options){

this.getSwiperList();
},
//获取轮播图数据的方法
getSwiperList(){
request({url:"https://api-hmugo-web.itheima.net/api/public/v1/home/swiperdata"}).then(res=>{
this.setData({
swiperList:res.data.message
})
})
},
}

index.wxml

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
<!-- 轮播图 -->
<view class="index_swiper">
<swiper
indicator-dots="{{true}}"
autoplay="{{true}}"
interval="{{3000}}"
duration="{{500}}"
indicator-active-color="#FFFFFF"
circular="{{true}}">
<!--
1 swiper标签存在默认宽度和高度
100% * 150px
2 images 也存在默认的宽度和高度
320px * 240px
3 设计图片和轮播图
1 先看原图的宽高比 750*340
2 让图片的高度自动适应 宽度等于100%
3 让swiper标签的高度变成和图片的高一样即可
4 图片标签
mode属性 渲染模式
widthFix 让图片标签宽高 和 图片标签的内容的宽高等比例发生变化
-->
<block wx:for="{{swiperList}}" wx:key="goods_id">
<swiper-item>
<navigator>
<image class="swiper-image" src="{{item.image_src}}" mode="widthFix"/>
</navigator>
</swiper-item>
</block>
</swiper>
</view>
<!-- 轮播图 -->

index.less

1
2
3
4
5
6
7
8
9
10
11
//设置轮播图的图片宽度为100%
.swiper-image{
width: 100%;
}
// 让外层的swiper标签等于原图的宽高
.index_swiper{
swiper{
width: 750rpx;
height: 340rpx;
}
}
13.7.1.2.分类导航

index.wxml

1
2
3
4
5
6
7
8
9
10
<!--导航 -->
<view class="index_cate">
<block wx:for="{{catesList}}"
wx:key="name">
<navigator >
<image mode="widthFix" src="{{item.image_src}}"></image>
</navigator>
</block>
</view>
<!--导航 -->

index.less

1
2
3
4
5
6
7
8
9
10
11
.index_cate{
display: flex;
height: 100rpx;
padding: 20rpx;
navigator{
flex: 1;
image{
width: 100%;
}
}
}

2020年7月1日

web中的本地存储和 小程序的本地存储的区别

1 编写代码的方式不一样了*

web:localStorage.setItem(“key”,”value”) localStorage.getItem(“key”)*

小程序: wx.setStorageSync(“key”,”value”); wx.getStorageSync(‘key’);*

2 存储的时候 有没有做类型转换*

web:不管存入的是什么类型的数据,最终都会先调用以下 toString(),把数据变成字符串 再存入

小程序: 不存再类型转换的这个操作,即存储的时候是什么类型 获取的时候就是什么类型

小程序中支持es7的async语法

es7的async号称是解决回调地狱的最终方案

  1. 小程序开发工具中,勾选es6转es5语法

  2. 下载facebook的regenerator库中的 regenerator/packages/regenerator-runtime/runtime.js

  3. 在小程序目录下新建文件夹 lib/runtime/runtime.js,将代码copy进去

  4. 在每一个需要使用saync语法的页面js文件中,都引入(不能全局引入)

    1
    import regeneratorRuntime from '../../lib/runtime/runtime';

Async / await

Promise的Async/await

async/await是es7推出的一套关于异步的终极解决方案,为什么要说他是终极解决方案呢?因为他实在是太好用了,而且写起来还非常的简单。

什么是async/await呢?可以总结为一句话:async/await是一对好基友,缺一不可,他们的出生是为Promise服务的。可以说async/await是Promise的进化版。

这两个基友必须同时出现,缺一不可

语法:

1
2
3
4
5
6
7
8
9
10
11
12

1 async function (function return Promise)
函数返回Promise对象
promise对象的结果由async函数执行的返回值决定

2 await expression (value or Promise)
expression一般是Promise对象,也可以是其他值
如果是Promise对象,await返回的是Promise成功的值
如果是其他值,直接将此值作为await的返回值

3 await必须写在async中,但async可以没有await
如果awaitPromise失败,就会抛出异常,需通过trycatch…捕获处理

注:await右侧表达式为Promise,得到的结果就是promise成功的value

注:await右侧表达式不为Promise,得到的结果就是它本身

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
function set1() {
return new Promise((r, j) => {
setTimeout(() => {
console.log("3000");
r(333);
}, 3000)
})
}

function set2() {
return new Promise((r, j) => {
setTimeout(() => {
console.log("2000");
r(222);
}, 2000)
})
}

async function fn1() {
const s1 = await set1();
const s2 = await set2();
console.log(s1);
console.log(s2);
}

fn1();
------------------------------------------------------
// 错误处理 - try catch

async function fn5(){
try{
const value = await fn2()
console.log('value', value)
}catch(error){ //捕获失败promise的结果
console.log('error', error)
}
}
fn5()

按顺序处理多个 async(异步) 返回值:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
JavaScript 代码:
async function asyncFunc() {
const result1 = await otherAsyncFunc1();
console.log(result1);
const result2 = await otherAsyncFunc2();
console.log(result2);
}

// 等价于:
function asyncFunc() {
return otherAsyncFunc1()
.then(result1 => {
console.log(result1);
return otherAsyncFunc2();
})
.then(result2 => {
console.log(result2);
});
}

并行处理多个 async(异步) 返回值:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
async function asyncFunc() {
const [result1, result2] = await Promise.all([
otherAsyncFunc1(),
otherAsyncFunc2(),
]);
console.log(result1, result2);
}

// 等价于:
function asyncFunc() {
return Promise.all([
otherAsyncFunc1(),
otherAsyncFunc2(),
])
.then([result1, result2] => {
console.log(result1, result2);
});
}

错误处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
async function asyncFunc() {
try {
await otherAsyncFunc();
} catch (err) {
console.error(err);
}
}

// 等价于:
function asyncFunc() {
return otherAsyncFunc()
.catch(err => {
console.error(err);
});
}
谢谢老板