微信小程序
一、微信小程序介绍
微信⼩程序,简称⼩程序,英⽂名 Mini Program
,是⼀种不需要下载安装即可使⽤的应⽤,它实现
了应用“触⼿可及”的梦想,用户扫⼀扫或搜⼀下即可打开应⽤
1.1 概述
1、微信有海量⽤⼾,⽽且粘性很⾼,在微信⾥开发产品更容易触达⽤⼾;
2、推⼴app或公众号的成本太⾼。
3、开发适配成本低。
4、容易⼩规模试错,然后快速迭代。
5、跨平台。
1.2 历史
- 2016年1⽉11⽇,微信之⽗张⼩⻰时隔多年的公开亮相,解读了微信的四⼤价值观。张⼩⻰指出,越来越多产品通过公众号来做,因为这⾥开发、获取⽤⼾和传播成本更低。拆分出来的服务号并没有提供更好的服务,所以微信内部正在研究新的形态,叫「微信⼩程序」需要注意的是,之前是叫做应⽤号
- 2016年9⽉21⽇,微信⼩程序正式开启内测。在微信⽣态下,触⼿可及、⽤完即⾛的微信⼩程序引起⼴泛关注。腾讯云正式上线微信⼩程序解决⽅案,提供⼩程序在云端服务器的技术⽅案。
- 2017年1⽉9⽇,微信推出的“⼩程序”正式上线。“⼩程序”是⼀种⽆需安装,即可使⽤的⼿机“应⽤”。不需要像往常⼀样下载App,⽤⼾在微信中“⽤完即⾛”。
二、小程序结构目录
小程序框架的目标是通过尽可能简单、高效的方式让开发者可再微信中开发具有原生 APP 体验的服务
小程序框架提供了自己的视图层描述语言 WXML
和 WXSS
,以及 JavaScript
,并在视图层与逻辑层间提供了数据传输和事件系统,让开发者能够专注于数据与逻辑
2.1 小程序文件结构和传统 web 对比
结构 | 传统web | 微信小程序 |
---|---|---|
结构 | HTML | WXML |
样式 | CSS | WXSS |
逻辑 | Javascript | Javascript |
配置 | 无 | JSON |
通过以上对比得出,传统web 是三层结构。而微信小程序是四层结构,多了一层 配置.json
2.2 基本的项目目录
三、小程序配置文件
一个小程序应用程序会包括最基本的两种配置文件。一种是全局的 app.json
和 页面自己的 page.json
注意:配置文件中不能出现注释
3.1 全局配置 app.json
app.json
是当前⼩程序的全局配置,包括了⼩程序的所有⻚⾯路径、界⾯表现、⽹络超时时间、底
部 tab
等。普通快速启动项⽬⾥边的 app.json
配置
{
"pages":[
"pages/index/index",
"pages/logs/logs"
],
"window":{
"backgroundTextStyle":"light",
"navigationBarBackgroundColor": "#fff",
"navigationBarTitleText": "WeChat",
"navigationBarTextStyle":"black"
}
}
字段的含义:
1、page
字段 – 用于描述当前小程序所有的页面路径,是为了让微信客户端知道当前你的小程序页面定义在哪个目录
2、window
字段 – 定义小程序所有页面的顶部背景颜色、文字颜色定义等
3.1.1 tabbar
3.2 页面配置 page.json
page.json
是用来表示页面目录下的 page.json
这类和小程序页面相关的配置。
开发者可独立定义每个页面的一些属性,如顶部颜色、是否允许下拉刷新等等
页面的配置只能设置 app.json
中的 window
配置项的内容,页面中配置项会覆盖 app.json
的 window
中相同的配置项
属性 | 类型 | 默认值 | 描述 |
---|---|---|---|
navigationBarBackgroundColor | HexColor | #000000 | 导航栏背景颜⾊,如 #000000 |
navigationBarTextStyle | String | white | 导航栏标题颜⾊,仅⽀持 black / white |
navigationBarTitleText | String | 导航栏标题⽂字内容 | |
backgroundColor | HexColor | #ffffff | 窗⼝的背景⾊ |
backgroundTextStyle | String | dark | 下拉 loading 的样式,仅⽀持 dark / light |
enablePullDownRefresh | Boolean | false | 是否全局开启下拉刷新 |
onReachBottomDistance | Number | 50 | ⻚⾯上拉触底事件触发时距⻚⾯底部距离,单位为px |
disableScroll | Boolean | false | 设置为 true 则⻚⾯整体不能上下滚动;只在⻚⾯配置中有效,⽆法在 app.json 中设置该项 |
3.3 sitemap 配置
⼩程序根⽬录下的 sitemap.json
⽂件⽤于配置⼩程序及其⻚⾯是否允许被微信索引
四、模板语法
WXML(WeiXin Markup Language)
是框架设计的一套标签语言,结合基础组件、事件系统,可构建出页面的结构
4.1 数据绑定
<!--
1 text 相当于以前web中的 span标签 行内元素 不会换行
2 view 相当于以前web中的 div标签 块级元素 会换行
3 checkbox 以前的复选框标签
-->
4.1.1 普通写法
<!-- 1 字符串 -->
<view> {{msg}} </view>
<!-- 2 数字类型 -->
<view>{{num}}</view>
<!-- 3 bool类型 -->
<view> 是否是伪娘: {{isGirl}} </view>
<!-- 4 object类型 -->
<view>{{person.age}}</view>
<view>{{person.height}}</view>
<view>{{person.weight}}</view>
<view>{{person.name}}</view>
<!-- 5 在标签的属性中使用 -->
<view data-num="{{num}}"> 自定义属性</view>
Page({
data: {
msg: "hello mina",
num: 10000,
isGirl: false,
person: {
age: 74,
height: 145,
weight: 200,
name: "富婆"
},
isChecked:false,
list:[
{
id:0,
name:"猪八戒"
},
{
id:1,
name:"天蓬元帅"
},
{
id:2,
name:"悟能"
}
]
}
});
4.1.2 组件属性
<view id="item-{{id}}"> </view>
Page({
data: {
id: 0
}
})
4.1.3 bool 类型
不要直接写 checked=“false”,其计算结果是一个字符串
<!--
6 使用bool类型充当属性 checked
1 字符串和 花括号之间一定不要存在空格 否则会导致识别失败
以下写法就是错误的示范
<checkbox checked=" {{isChecked}}"> </checkbox>
-->
<view>
<checkbox checked="{{isChecked}}"> </checkbox>
</view>
4.2 运算
4.2.1 三元运算符
<view hidden="{{flag ? true : false}}"> Hidden </view>
4.2.2 算数运算
<view> {{a + b}} + {{c}} + d </view>
Page({
data: {
a: 1,
b: 2,
c: 3
}
})
4.2.3 逻辑判断
<view wx:if="{{length > 5}}"> </view>
4.2.4 字符串运算
<!--
7 运算 => 表达式
1 可以在花括号中 加入 表达式 -- “语句”
2 表达式
指的是一些简单 运算 数字运算 字符串 拼接 逻辑运算。。
1 数字的加减。。
2 字符串拼接
3 三元表达式
3 语句
1 复杂的代码段
1 if else
2 switch
3 do while 。。。。
4 for 。。。
-->
<view>{{1+1}}</view>
<view>{{'1'+'1'}}</view>
<view>{{ 11%2===0 ? '偶数' : '奇数' }}</view>
4.2.5 注意
花括号和引号之间如果有空格,将最终被解析成为字符串
4.3 列表渲染
4.3.1 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"
例子:
<!--
8 列表循环
1 wx:for="{{数组或者对象}}" wx:for-item="循环项的名称" wx:for-index="循环项的索引"
2 wx:key="唯一的值" 用来提高列表渲染的性能
1 wx:key 绑定一个普通的字符串的时候 那么这个字符串名称 肯定是 循环数组 中的 对象的 唯一属性
2 wx:key ="*this" 就表示 你的数组 是一个普通的数组 *this 表示是 循环项
[1,2,3,44,5]
["1","222","adfdf"]
3 当出现 数组的嵌套循环的时候 尤其要注意 以下绑定的名称 不要重名
wx:for-item="item" wx:for-index="index"
4 默认情况下 我们 不写
wx:for-item="item" wx:for-index="index"
小程序也会把 循环项的名称 和 索引的名称 item 和 index
只有一层循环的话 (wx:for-item="item" wx:for-index="index") 可以省略
9 对象循环
1 wx:for="{{对象}}" wx:for-item="对象的值" wx:for-index="对象的属性"
2 循环对象的时候 最好把 item和index的名称都修改一下
wx:for-item="value" wx:for-index="key"
-->
<view>
<view
wx:for="{{list}}"
wx:for-item="item"
wx:for-index="index"
wx:key="id"
>
索引:{{index}}
--
值:{{item.name}}
</view>
</view>
<view>
<view>对象循环</view>
<view
wx:for="{{person}}"
wx:for-item="value"
wx:for-index="key"
wx:key="age"
>
属性:{{key}}
--
值:{{value}}
</view>
</view>
Page({
data: {
person: {
age: 74,
height: 145,
weight: 200,
name: "富婆"
},
list:[
{
id:0,
name:"猪八戒"
},
{
id:1,
name:"天蓬元帅"
},
{
id:2,
name:"悟能"
}
]
}
});
4.3.2 block
渲染⼀个包含多节点的结构块?block最终不会变成真正的dom元素
<block wx:for="{{[1, 2, 3]}}" wx:key="*this" >
<view> {{index}}: </view>
<view> {{item}} </view>
</block>
例子
<!--
10 block
1 占位符的标签
2 写代码的时候 可以看到这标签存在
3 页面渲染 小程序会把它移除掉
-->
<view>
<block
wx:for="{{list}}"
wx:for-item="item"
wx:for-index="index"
wx:key="id"
class="my_list"
>
索引:{{index}}
--
值:{{item.name}}
</block>
</view>
4.4 条件渲染
4.4.1 wx:if
在框架中,使⽤ wx:if="{{condition}}"
来判断是否需要渲染该代码块:
<view wx:if="{{false}}">1</view>
<view wx:elif="{{true}}">2</view>
<view wx:else>3</view>
4.4.2 hidden
<view hidden="{{condition}}"> True </view>
两者对比
<!--
11 条件渲染
1 wx:if="{{true/false}}"
1 if , else , if else
wx:if
wx:elif
wx:else
2 hidden
1 在标签上直接加入属性 hidden
2 hidden="{{true}}"
3 什么场景下用哪个
1 当标签不是频繁的切换显示 优先使用 wx:if
直接把标签从 页面结构给移除掉
2 当标签频繁的切换显示的时候 优先使用 hidden
通过添加样式的方式来切换显示
hidden 属性 不要和 样式 display一起使用
-->
<view>
<view>条件渲染</view>
<view wx:if="{{true}}">显示</view>
<view wx:if="{{false}}">隐藏</view>
<view wx:if="{{flase}}">1</view>
<view wx:elif="{{flase}}">2 </view>
<view wx:else> 3 </view>
<view>---------------</view>
<view hidden >hidden1</view>
<view hidden="{{false}}" >hidden2</view>
<view>-----000-------</view>
<view wx:if="{{false}}">wx:if</view>
<view hidden style="display: flex;" >hidden</view>
</view>
五、小程序事件的绑定
小程序中绑定事件,通过 bind 关键字来实现。如 bindtap、bindinput、bindchange
等不同的组件支持不同的事件。
5.1 wxml
<input bindinput="handleInput" />
5.2 page
Page({
// 绑定的事件
handleInput: function(e) {
console.log(e);
console.log("值被改变了");
}
})
5.3 实例
<!--
1 需要给input标签绑定 input事件
绑定关键字 bindinput
2 如何获取 输入框的值
通过事件源对象来获取
e.detail.value
3 把输入框的值 赋值到 data当中
不能直接
1 this.data.num=e.detail.value
2 this.num=e.detail.value
正确的写法
this.setData({
num:e.detail.value
})
4 需要加入一个点击事件
1 bindtap
2 无法在小程序当中的 事件中 直接传参
3 通过自定义属性的方式来传递参数
4 事件源中获取 自定义属性
-->
<input type="text" bindinput="handleInput" />
<button bindtap="handletap" data-operation="{{1}}" >+</button>
<button bindtap="handletap" data-operation="{{-1}}">-</button>
<view>
{{num}}
</view>
Page({
data: {
num: 0
},
// 输入框的input事件的执行逻辑
handleInput(e) {
// console.log(e.detail.value );
this.setData({
num: e.detail.value
})
},
// 加 减 按钮的事件
handletap(e) {
// console.log(e);
// 1 获取自定义属性 operation
const operation = e.currentTarget.dataset.operation;
this.setData({
num: this.data.num + operation
})
}
})
5.4 特别注意
1、绑定事件时不能带参数,不能带括号,以下为错误写法
<input bindinput="handleInput(100)" />
2、事件传值,通过标签自定义属性的方式和 value
<input bindinput="handleInput" data-item="100" />
3、事件触发时获取数据
handleInput: function(e) {
// {item:100}
console.log(e.currentTarget.dataset)
// 输入框的值
console.log(e.detail.value);
}
六、样式 WXSS
WXSS(WeiXin Style Sheets)
是一套样式语言,用于描述 WXML
的组件样式
与 CSS 相比,WXSS 扩展的特性有:
- 响应式长度单位
rpx
- 样式导入
6.1 尺寸单位
rpx (responsive pixel):可根据屏幕宽度进行自适应。规定屏幕宽为 750rpx。如在 iPhone 上,屏幕宽度为 375px,共有 750 个物理像素,则 750rpx = 375px = 750物理像素,1rpx = 0.5px = 1物理像素
设备 | 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 |
建议:开发微信小程序时设计师可用 iPhone 作为视觉稿的标准
使用步骤:
1、确定设计稿宽度 pageWidth
2、计算比例 750rpx = pageWidth px
,因此 1px = 750rpx/pageWidth
3、在less文件中,只要把设计稿中的 px => 750/pageWidth rpx
即可
/*
1 小程序中 不需要主动来引入样式文件
2 需要把页面中某些元素的单位 由 px 改成 rpx
1 设计稿 750x
750 px = 750 rpx
1 px = 1 rpx
2 把屏幕宽度 改成 375px
375 px = 750 rpx
1 px = 2rpx
1rpx = 0.5px
3 存在一个设计稿 宽度 414 或者 未知 page
1 设计稿 page 存在一个元素 宽度 100px
2 拿以上的需求 去实现 不同宽度的页面适配
page px = 750 rpx
1 px = 750 rpx / page
100 px = 750 rpx * 100 / page
假设 page = 375px
4 利用 一个属性 calc属性 css 和 wxss 都支持 一个属性
1 750 和 rpx 中间不要留空格
2 运算符的两边也不要留空格
*/
view{
/* width: 200rpx; */
height: 200rpx;
font-size: 40rpx;
background-color: aqua;
/* 以下代码写法是错误 */
/* width:750 rpx * 100 / 375 ; */
width:calc(750rpx * 100 / 375);
}
6.2 样式导入
wxss 中直接就支持,样式导入功能,也可和 less 中的导入混用
使用 @import
语句可导入外联样式表,只支持相对路径
代码:
/** common.wxss **/
.small-p {
padding:5px;
}
/** app.wxss **/
@import "common.wxss";
.middle-p {
padding:15px;
}
6.3 选择器
特别需要注意的是⼩程序?不⽀持通配符 *
因此以下代码⽆效!
*{
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 组件前边插⼊内容 |