一)何为微信小程序
张小龙说:小程序是一种不需要安装即可使用的应用,它实现了应用“触手可及”的梦想,用户扫一扫或者搜一下即可打开应用。也体现了“用完即走”的理念,用户不用关心是否安装太多应用的问题。应用将无处不在,随时可用,但又无需安装卸载。
小程序能做什么:查天气、查交通、翻译、点餐、娱乐……都可以实现,覆盖了生活的方方面面。
小程序的定位:比网站体验好——可以使用手机原生的底层接口,比如重力、罗盘、电话、网络状况等;而且小程序底层有使用react技术,比如wxml转化为html。
二)如何开发微信小程序
1、技术介绍
1)开发小程序所用的技术
WXML:页面布局,可以理解为类似于HTML(但是WXML还得结合WXS);
WXSS:页面样式,可以理解为类似于CSS;
WXS/Javascript:页面的脚本代码,可以使用JS或者WXS来编写,WXS(WeiXin Script)是小程序的一套脚本语言,结合
WXML
,可以构建出页面的结构。
WXSS和WXS二者的解析:
WXSS (是CSS的扩展):WXSS | 微信开放文档
WXS小程序脚本语言介绍:WXS | 微信开放文档
2)WeUI
WeUI 是一套同微信原生视觉体验一致的基础样式库,由微信官方设计团队为微信内网页和微信小程序量身设计,令用户的使用感知更加统一。
它包含了button
、cell
、dialog
、 progress
、 toast
、article
、actionsheet
、icon
等各式元素。
2、开发准备
1)首先你得注册小程序,并且获取小程序的测试号ID(APPID)
注册小程序:微信小程序
申请测试号:测试号管理 | 微信公众平台
2)然后,下载安装小程序开发工具
下载安装地址:微信开发者工具下载地址与更新日志 | 微信开放文档
安装:默认点击下一步安装,安装好之后扫码登录。
3、开始开发
这里以一个简单的HelloWorld项目为例进行说明。
1)扫码登陆之后,进到新建项目界面,填好项目信息,选择你的测试号,点击“新建”即可
说明:语言可以选择Javascript或Typescript,这里选择Javascript即可。
2)项目创建完成之后,进到开发工具界面,就开始进行开发
说明:开发工具界面包括三大部分——模拟器、编辑器和调试器。
另外,如果需要对项目进行其他参数(如调试的api版本、项目名、编译的其他选项)配置和修改,可在“详情”选项里进行修改:
3)项目目录结构介绍
项目目录结构主要包括:项目页面,工具类,整个小程序配置,项目配置文件。
整个项目的处理逻辑是这样的:
4)app.json文件介绍
它是用来对微信小程序进行全局配置的文件,决定页面的路径、窗口表现、设置网络超时时间、设置多 tab 等。
一个配置例子:
{
//1.页面的路径
"pages": [
"pages/index/index", //第一个代表小程序的初始页面
"pages/logs/index"
],
//2.窗口表现
"window": {
"navigationBarTitleText": "Demo"
},
//3.设置多个底部的tab
"tabBar": {
"list": [{
"pagePath": "pages/index/index",
"text": "首页"
}, {
"pagePath": "pages/logs/logs",
"text": "日志"
}]
},
//4.设置网络超时时间
"networkTimeout": {
"request": 10000,
"downloadFile": 10000
},
//5.debug开发模式
"debug": true
}
注意:
1)配置文件所有的路径前面不要写:“./../”,也就是说,pages目录就是它的根目录了,不能再往上;
2)每一个配置属性最后面一个配置项不能有逗号,例如“pages/logs/index”后面不能再加逗号;
3)配置文件都是以key : value 的字符串形式。
app.json每一个配置属性说明:
pages 属性
接受一个数组,每一项都是字符串,来指定小程序由哪些页面组成;
每一项代表对应页面的【路径+文件名】信息,数组的第一项代表小程序的初始页面;
小程序中新增/减少页面,都需要对 pages 数组进行修改。
文件名不需要写文件后缀,因为框架会自动去寻找路径下 .json/
.js/
.wxml/
.wxss
四个文件进行整合。
"pages": [
"pages/index/index", //代表小程序的初始页面,文件名不需要写文件后缀
"pages/logs/index"
],
window 属性
用于设置小程序的状态栏、导航条、标题、窗口背景色。
"window":{
"navigationBarBackgroundColor": "#06C1AE", // 状态栏的背景
"navigationBarTitleText": "首页", // 状态栏中的文本
"navigationBarTextStyle":"white", //状态栏中的文本样式(仅支持 black/white)
"navigationStyle":"custom", //沉浸式导航栏
"enablePullDownRefresh":true, //允许所有页面的下拉刷新,允许回调 onPullDownRefresh 这个函数
"backgroundColor":"green", //窗口的背景
"backgroundTextStyle":"dark", //下拉背景字体、loading 图的样式,仅支持 dark/light
"onReachBottomDistance":"200rpx" //距离内容的底部200rpx的时候回调onReachBottom这个函数
}
tabBar 属性
如果小程序是一个多 tab 应用(客户端窗口的底部或顶部有 tab 栏可以切换页面),可以通过 tabBar 配置项指定 tab 栏的表现,以及 tab 切换时显示的对应页面。
"tabBar": {
"color":"#989898",
"selectedColor":"#FF6802",
"list":[
{
"pagePath": "pages/index/index",
"text": "首页",
"iconPath": "image/find_icon_nor.png",
"selectedIconPath": "image/find_icon_press.png"
},
{
"pagePath": "pages/logs/logs",
"text": "日志",
"iconPath": "image/find_icon_nor.png",
"selectedIconPath": "image/find_icon_press.png"
}
]
}
注意:
当设置 position 为 top 时,将不会显示 icon;
tabBar 中的 list 是一个数组,只能配置最少2个、最多5个 tab,tab 按数组的顺序排序。
networkTimeout 属性
"networkTimeout":{
"request":50000,
"connectSocket":50000,
"uploadFile":50000,
"downloadFile":50000
}
注意:默认超时时间为60000。
debug 属性
可以在开发者工具中开启 debug 模式,在开发者工具的控制台面板,调试信息以 info 的形式给出,其信息有page的注册
,页面路由
,数据更新
,事件触发
。
可以帮助开发者快速定位一些常见的问题。
"debug":true
5)app.js文件介绍
App(Object)函数
App()函数用来注册一个小程序,接受一个
Object
参数,其指定小程序的生命周期回调等;App()必须在 app.js 中调用,必须调用且只能调用一次,不然会出现无法预期的后果。
每个小程序都有一个App实例对象。
App的生命周期
App({
/**
* 生命周期回调—监听小程序初始化
* 小程序初始化完成时(全局只触发一次)
* options:包含打开小程序的路径,打开小程序的场景值
*/
onLaunch: function(options) {
// Do something initial when launch.
},
/**
* 生命周期回调—监听小程序显示
* 小程序启动,或从后台进入前台显示时
*/
onShow: function(options) {
// Do something when show.
},
/**
* 生命周期回调—监听小程序隐藏
* 小程序从前台进入后台时
*/
onHide: function() {
// Do something when hide.
},
})
6)app.wxss样式文件
定义在 app.wxss 中的样式为全局样式,作用于每一个页面。
在 pages 的 wxss 文件中定义的样式为局部样式,只作用在对应的页面,并会覆盖 app.wxss 中相同的选择器:
7)一个页面的目录介绍
一个页面的目录下包含四个文件,分别指代的是:页面逻辑(逻辑代码),页面配置,页面布局,页面样式。
(1)js文件
Page(Object)函数
该函数用来注册一个页面,接受一个 Object
类型参数,其指定页面的初始数据、生命周期回调、事件处理函数等。
页面的生命周期
以几个典型的例子进行说明:
1)当打开一个页面的时,执行下面的生命周期函数:
onLoad --> onShow -- > onReady
2)当小程序切换到后台(例如:按下home建),执行:
onHide
3)当小程序切换到前台的时候,执行:
onShow
4)当页面被销毁的时候,执行:
onUnload
5.1)当A页面切换tabbar到B页面的生命周期
A:onLoad --> onShow -- > onReady --> onHide
B:onLoad --> onShow -- > onReady
5.2)当B页面切换tabbar到A页面的生命周期
B:onHide
A:onShow
6.1)当A页面跳转到B页面的生命周期( 与5.1一样 )
A:onLoad --> onShow -- > onReady --> onHide
B:onLoad --> onShow -- > onReady
6.2)当B页面返回到A页面的生命周期
B:onUnload
A:onShow
生命周期函数的代码说明如下:
Page({
/**
* 1.生命周期函数--监听页面加载
* options:可以获取到上一个页面传递过来的参数
*/
onLoad: function (options) {
//一般在这里执行网络请求
console.log('onLoad');
},
/**
* 2.生命周期函数--监听页面显示
*/
onShow: function () {
console.log('onShow');
},
/**
* 3.生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
//界面渲染完成后可以获取组件对象
console.log('onReady');
},
/**
* 4.生命周期函数--监听页面隐藏
*/
onHide: function () {
console.log('onHide');
},
/**
* 5.生命周期函数--监听页面卸载
*/
onUnload: function () {
console.log('onUnload');
},
})
注意:
1)小程序框架的逻辑层并非运行在浏览器中,因此 JavaScript 在 web 中一些能力都无法使用,如 window,document 等;
2)小程序的JS有一些额外的成员:
- App 方法:用于定义应用程序实例对象
- Page 方法:用于定义页面对象
- getApp 方法:用来获取全局应用程序对象
- getCurrentPages 方法:用来获取当前页面的调用栈
- wx对象:提供了核心API
3)小程序中支持CommonJS规范。
8)常用组件介绍
view
视图组件,类似于html的div。
常用属性说明:
属性名 | 类型 | 默认值 | 说明 | 最低基础库版本号 |
hover-class | String | none | 指定按下去的样式类。 1)当 2)当 hover-class="className" 时,等于设置样式效果。 例如:按下去改变view背景的透明度。 | |
hover-stop-propagation | Boolean | false | 指定是否阻止本节点的祖先节点出现点击态。 | 1.5.0 |
hover-start-time | Number | 50 | 按住后多久出现点击态,单位毫秒。 | |
hover-stay-time | Number | 400 | 手机松开后点击态保留时间,单位毫秒。 |
代码举例:
<view hover-class='hover-class-style'>
我是一个view
</view>
.hover-class-style{
opacity:0.7
}
说明:样式的写法有三种——行内样式、页内样式和外部样式。
另外,目前支持的选择器有:
选择器 | 样例 | 样例描述 |
---|---|---|
.class | .intro | 选择所有拥有 class="intro" 的组件(类选择器) |
#id | #firstname | 选择拥有 id="firstname" 的组件(id 选择器) |
element | view | 选择所有 view 组件(标签选择器) |
element , element | view, checkbox | 选择所有的 view 组件和所有的 checkbox 组件(并列) |
::after | view::after | 在 view 组件后边插入内容( 伪元素选着器 ) |
::before | view::before | 在 view 组件前边插入内容( 伪元素选着器 ) |
image
图片组件,用于加载显示图片。
常用属性:image | 微信开放文档
1)加载项目中的图片(src=相对路径);
2)加载网络中的图片(src=http);
3)加载手机图库中的图片(src=tempFilePath)。
代码举例:
<!-- 本地图片 -->
<image src="../images/test.png" style="width:200px;height:300px;"></image>
<!-- 网络图片 -->
<image src="https://www.baidu.com/img/bd_logo1.png" style="width:200px;height:300px;"></image>
另外,一个常用的属性是mode,可以对图片进行缩放。常用的三个属性值:
值 | 说明 | 最低版本 |
---|---|---|
scaleToFill | 缩放模式,不保持纵横比缩放图片,使图片的宽高完全拉伸至填满 image 元素 | |
aspectFit | 缩放模式,保持纵横比缩放图片,使图片的长边能完全显示出来。也就是说,可以完整地将图片显示出来。 | |
aspectFill | 缩放模式,保持纵横比缩放图片,只保证图片的短边能完全显示出来。也就是说,图片通常只在水平或垂直方向是完整的,另一个方向将会发生截取。 |
代码举例:
<image src="../images/test.png" style="width:200px;height:300px;" mode="scaleToFill"></image>
<image src="../images/test.png" style="width:200px;height:300px;" mode="aspectFit"></image>
<image src="../images/test.png" style="width:200px;height:300px;" mode="aspectFill"></image>
其余属性值请查阅:image | 微信开放文档
加载手机图库中的图片
tempFilePath可以作为img标签的src属性显示图片 。
// 单击按钮,打开相册或拍照
clickToOpenPotho: function () {
//1.打开手机的相册,选中图片按了确认键后回调success中的函数
var self = this
wx.chooseImage({
count: 1, //默认9
sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
sourceType: ['album', 'camera'], //可以指定来源是相册还是相机,默认二者都有
success: function (res) {
//2.返回选定照片的本地文件路径列表,tempFilePath可以作为img标签的src属性显示图片
self.setData({
myImageUrl: res.tempFilePaths //["http://tmp/wxf159d92196fdb44f.o6…………………….jpg"]
})
console.log(res)
}
})
}
text
文本组件,输入普通文本信息。
使用举例:
<view>
<text>我是第一个文本\n</text>
<text>我是第二个文本\n</text>
<text>我是第三个文本\n</text>
<text>我是第四个文本\n</text>
</view>
说明:这里加了“\n”转义字符作为换行,也可以使用view进行换行:
另外,text组件还可以绑定数据,数据绑定使用双大括号 {{}} 形式,举例如下:
说明:上面使用了wx:if和wx:else进行渲染判断。在框架( 布局 )中,使用 wx:if="{{true}}"
来判断是否需要渲染该代码块(组件),判断的值为boolean值:
wx:if和hidden的区别
1)wx:if
是惰性的,如果在初始渲染条件为false
,框架什么也不做,在条件第一次变成true的时候才开始局部渲染;
2)hidden
属性就简单的多,组件始终会被渲染,只是简单的控制显示与隐藏。
因此,如果需要频繁切换的情景下,用 hidden
更好,如果在运行时条件不大可能改变则 wx:if
较好。
注意:给组件添加boolean
类型的属性值要使用双大括号{{true/false}}。
input
输入组件,用于输入文本或者密码。
input组件最好不要设置宽为100%,只设置高度:
input{
background: #dddddd;
height: 80rpx;
color: white;
}
常用属性如下:
属性名 | 类型 | 默认值 | 说明 | 最低版本 |
---|---|---|---|---|
value | String | 输入框的初始内容 | ||
type | String | "text" | input 的类型(有appid才有效果) | |
password | Boolean | false | 是否是密码类型 | |
placeholder | String | 输入框为空时占位符 | ||
placeholder-style | String | 指定 placeholder 的样式 | ||
placeholder-class | String | "input-placeholder" | 指定 placeholder 的样式类 | |
disabled | Boolean | false | 是否禁用 | |
maxlength | Number | 10 | 最大输入长度,设置为 -1 的时候不限制最大长度( 例如:最大10个字母或者中文 ) |
代码举例如下:
<input type="text" value="" placeholder="请输入文本" ></input>
<input password="{{true}}" value="" placeholder="请输入文本" ></input>
常用事件:
bindinput | EventHandle | 当键盘输入时,触发input事件,event.detail = {value, cursor},处理函数可以直接 return 一个字符串,将替换输入框的内容。 | ||
---|---|---|---|---|
bindfocus | EventHandle | 输入框聚焦时触发,event.detail = {value: value} | ||
bindblur | EventHandle | 输入框失去焦点时触发,event.detail = {value: value} |
代码举例如下。
绑定事件:
<input password="{{true}}" value="" placeholder="请输入文本" bindinput="onBindinput"></input>
通过事件获取值,并保存在data里:
Page({
data:{
passWord:null
},
onLoad:function(){},
onBindinput:function(event){
console.log(event.detail.value);
this.setData({
passWord:event.detail.value
})
}
})
注意:保存是 this.setData({}),获取是this.data.xxx。
然后将值显示在页面上:
<text>{{passWord}}</text>
button
按钮组件,用于实现按钮,一般绑定事件。
常用的属性有:
size:按钮的大小。
default mini
type:按钮的类型 , 不能与背景样式一起使用。
default warn primary
plain:按钮镂空。
plain="{{true}}" //true false
disabled:按钮不可点击。
disabled="{{true}}" //true false
loading:按钮显示进度条。
loading="{{true}}" //true false
hover-class:按钮按下的样式,注意是按钮按下的样式,不是放上去时,因为手机端没有鼠标放上去一说。
可以自定义任意按钮按下的样式,例如,按下时改变透明度 、颜色等等。
.btn-press {
background: green;
}
form-type:指定button为表单类型,即可提交表单。
//buttton.wxml布局
<form bindsubmit="obBindSubmit">
<input placeholder='请求用户名' name="username"></input>
<input placeholder='密码' password name="password"></input>
<button form-type='submit'>点击提交表单</button>
</form>
// buttton.js
obBindSubmit:function(e){
console.log(e.detail.value) //{ username:"xxxx", password:"xxxxx"}
}
open-type:微信开放能力。
属性值如下所示:
值 | 说明 | 最低版本 |
---|---|---|
contact | 打开客服会话,与微信小程序的客服会话 | 1.1.0 |
share | 触发用户转发小程序给微信朋友,使用前建议先阅读使用指引 | 1.2.0 |
getUserInfo | 获取用户信息,可以从bindgetuserinfo回调中获取到用户信息。(第一次调用会弹出:微信授权对话框) | 1.3.0 |
getPhoneNumber | 获取用户手机号,可以从bindgetphonenumber回调中获取到用户信息,(默认个人是不能获取)具体说明 | 1.2.0 |
launchApp | 打开APP,可以通过app-parameter属性设定向APP传的参数具体说明 | 1.9.5 |
openSetting | 打开授权设置页 | 2.0.7 |
feedback | 打开微信的“意见反馈”页面,用户可提交反馈内容并上传日志到微信小程序管理平台,开发者可以登录小程序管理后台后进入左侧菜单“客服反馈”页面获取到反馈内容 | 2.1.0 |
代码举例:
open-type="getUserInfo",获取用户信息,可以从bindgetuserinfo回调中获取到用户信息(第一次调用会弹出:微信授权对话框):
//buttton.wxml布局
<button open-type='getUserInfo' bindgetuserinfo="mygetuserinfo">getUserInfo</button>
// buttton.js
mygetuserinfo:function(e){
console.log(e.detail.userInfo) // {nickName: "xxx", gender: 0, language: "zh_CN",..}
}
scoll-view
用于垂直或者水平滚动内容。
(1)垂直滚动
代码举例如下。
wxml
<scroll-view scroll-y="{{true}}">
<view>view1</view>
<view>view2</view>
<view>view3</view>
</scoll-view>
注意:可以使用“wx:for”进行渲染,而且最好给出“wx:key”,不然会有警告:
<scroll-view wx:for="{{testArr}}" wx:key="*this" scroll-y="{{true}}">
<view>{{item}}</view>
</scoll-view>
*this:代表在 for 循环中的 item 本身,这种表示需要 item 本身是一个唯一的字符串或者数字,如果是对象则不可以。
两种方式的代码如下所示:
<block wx:for="{{array}}" wx:key="*this">
<view>{{item}}</view>
</block>
<block wx:for="{{objs}}" wx:key="{{item.id}}">
<view>{{item.id}}</view>
</block>
// js部分
data:{
array:[1,2,3],
objs:[{id:1},{id:2},{id:3},{id:4}]
}
wxss
scroll-view{
background: #dddddd;
/* 垂直滚动,这里给scroll-view设置高度 */
height: 600rpx;
}
scroll-view view{
height: 200rpx;
background: skyblue;
margin-bottom: 10rpx;
}
/* hidden scroll-view 的滚动条 */
::-webkit-scrollbar{
width: 0;
height: 0;
color:transparent;
}
说明:
第一步:给scroll-view添加scroll-y="{{true}}"属性;
第二步:给scroll-view设计高度,使用竖向滚动scroll-y时,需要给
scroll-view
一个固定高度,通过 WXSS 设置 height。
(2)水平滚动
代码举例如下。
wxml
<view>
<text>2.水平滚动</text>
<scroll-view scroll-x="true">
<view>view1</view>
<view>view2</view>
<view>view3</view>
<view>view4</view>
</scroll-view>
</view>
wxss
scoll-view{
width:100%;
background:red;
/*
white-space
normal:正常无变化(默认处理方式.文本自动处理换行.假如抵达容器边界内容会转到下一行)
pre: 保持HTML源代码的空格与换行,等同与pre标签
nowrap: 强制文本在一行,除非遇到br换行标签
pre-wrap: 同pre属性,但是遇到超出容器范围的时候会自动换行
pre-line: 同pre属性,但是遇到连续空格会被看作一个空格
inherit: 继承
*/
white-space: nowrap;
}
scoll-view view{
height:100rpx;
width:200rpx;
background:green;
/* 把组件类型给成行内块级标签:让view不占一行 */
display: inline-block;
}
rich-text
用于渲染html字符串模板或者渲染节点。
代码举例如下。
js
/**定义一个html字符串模板*/
const htmlSnip =
`
<div class="div-class">
<h1>Title</h1>
<p class="p">
Life is <i>like</i> a box of
<b> chocolates</b>.
</p>
<img class="img" src="https://www.baidu.com/img/bd_logo1.png?where=super"/>
<a href="https://www.baidu.com">A Link</a>
</div>
`
Page({
data:{
// html字符串
htmlSnip: htmlSnip,
// 定义节点
nodes: [{
name: 'div',
attrs: {
class: 'div-class',
style: 'line-height: 60px; color: #1AAD19;'
},
children: [
{
type: 'text',
text: 'You never know what you\'re gonna get.'
}
]
}]
}
})
wxml
<view>1.渲染html字符串</view>
<rich-text nodes="{{htmlSnip}}"></rich-text>
<view>2.使用节点渲染</view>
<rich-text nodes="{{nodes}}"></rich-text>
wxss
/* 选择器不能使用html标签 */
.div-class{
background: skyblue;
}
.p{
color: green;
}
.img{
width: 200rpx;
height: 100rpx;
}
说明:
1)如果是标签节点有下面属性(默认):
属性 | 说明 | 类型 | 必填 | 备注 |
---|---|---|---|---|
name | 标签名 | String | 是 | 支持部分受信任的HTML节点 |
attrs | 属性 | Object | 否 | 支持部分受信任的属性,遵循Pascal命名法 |
children | 子节点列表 | Array | 否 | 结构和nodes一致 |
{
name: 'div',
attrs: {},
children: [
]
}
2)如果是文本节点有下面一个给属性:
属性 | 说明 | 类型 | 必填 | 备注 |
---|---|---|---|---|
text | 文本 | String | 是 | 支持entities |
Page({
data:{
// 定义节点
nodes: [{
name: 'div',
attrs: {},
children: [
{
type: 'text',
text: 'You never know what you\'re gonna get.'
}
]
}]
}
})
web-view
是一个可以用来承载网页的容器,会自动铺满整个小程序页面。
个人类型与海外类型的小程序暂不支持使用。
属性名 | 类型 | 默认值 | 说明 |
---|---|---|---|
src | String | webview 指向网页的链接。可打开关联的公众号的文章,其它网页需登录小程序管理后台配置业务域名。 | |
bindmessage | EventHandler | 网页向小程序 postMessage 时,会在特定时机(小程序后退、组件销毁、分享)触发并收到消息。e.detail = { data } | |
bindload | EventHandler | 网页加载成功时候触发此事件。e.detail = { src } | |
binderror | EventHandler | 网页加载失败的时候触发此事件。e.detail = { src } |
<web-view src="https://m.jd.com/"></web-view>
说明:
1)网页可以使用JSSDK 1.3.2提供的接口实现:返回小程序页面、向小程序发送消息等等;
2)web-view中的bindmessage属性可以接受m站发送消息。
open-data
用于展示微信开放的数据( 不需要授权也可以获取部分的用户数据 ) ,基础库 1.4.0 开始支持,低版本需做兼容处理。
属性名 | 类型 | 默认值 | 说明 |
---|---|---|---|
type | String | 开放数据类型 | |
open-gid | String | 当 type="groupName" 时生效, 获取 群的 id | |
lang | String | en | 当 type="user*" 时生效,以哪种语言展示 userInfo,有效值有:en, zh_CN, zh_TW |
<open-data type="userNickName"></open-data>
<open-data type="userAvatarUrl"></open-data>
<open-data type="userNickName" lang="en"></open-data>
wxss
.header-style{
width:300rpx;
height:300rpx;
border-radius: 50%;
display: block;
background-color: red;
overflow: hidden;
}
注意:open-data组件圆头像如何实现?
overflow:hidde。
checkbox
用于多选项目。
属性名 | 类型 | 默认值 | 说明 |
---|---|---|---|
value | String | ``标识,选中时触发``的 change 事件,并携带 `` 的 value | |
disabled | Boolean | false | 是否禁用 |
checked | Boolean | false | 当前是否选中,可用来设置默认选中 |
color | Color | checkbox的颜色,同css的color ( 勾的颜色 ) |
wxml
<checkbox-group bindchange="onbindchange">
<checkbox value="玩游戏" checked="{{false}}" color="red">玩游戏</checkbox>
<checkbox value="看电影" checked="{{false}}" color="red">看电影</checkbox>
</checkbox-group>
js
/**
* 页面的初始数据
*/
data: {
},
onbindchange:function(event){
//监听checkbox的选择
console.log(event.detail)
},
注意:监听checkbox的选择需要:
1)添加 checkbox-group 监听;
2)checkbox 需要value属性。
label
用于包裹表单控件,改进表单控件的可用性。
比如页面有两个checkbox选项“玩游戏”和“看电影”,选择文字是没有选中效果的,只能点击选框才能选中。想要点击文本也能选中可以使用 label 改进表单组件的可用性。
属性名 | 类型 | 说明 |
---|---|---|
for | String | 绑定控件的 id |
目前可以绑定的控件有:button checkbox radio switch。
代码举例如下。
<checkbox-group bindchange="onbindchange">
<checkbox value="玩游戏" checked="{{false}}" color="red"></checkbox> <text>玩游戏</text>
<checkbox value="看电影" checked="{{false}}" color="red"></checkbox> <text>看电影</text>
</checkbox-group>
包裹label并且使用for属性改进之后:
<checkbox-group bindchange="onbindchange">
<checkbox id='check1' value="玩游戏" checked="{{false}}" color="red"></checkbox>
<label for='check1'><text>玩游戏</text></label>
<checkbox id='check2' value="看电影" checked="{{false}}" color="red"></checkbox>
<label for='check2'><text>看电影</text></label>
</checkbox-group>
for属性的优先级说明:
<view>
<!--label内部有多个控件也没有指定for属性的时候,默认选中第一个-->
<label>
<checkbox value="玩游戏" checked="{{false}}" color="red"></checkbox><text>玩游戏</text>
<checkbox value="看电影" checked="{{false}}" color="red"></checkbox><text>看电影</text>
<checkbox value="看电影" checked="{{false}}" color="red"></checkbox><text>看书</text>
</label>
</view>
<view>
<!--label内部有多个控件有指定for属性的时候,默认选中指定那个-->
<label for='check2'>
<checkbox value="玩游戏" checked="{{false}}" color="red"></checkbox><text>玩游戏</text>
<checkbox id='check2' value="看电影" checked="{{false}}" color="red"></checkbox><text>看电影</text>
<checkbox value="看电影" checked="{{false}}" color="red"></checkbox><text>看书</text>
</label>
</view>
radio
单选按钮。
属性名 | 类型 | 默认值 | 说明 |
---|---|---|---|
value | String | radio 标识。当该 radio 选中时,radio-group 的 change 事件会携带radio 的value | |
checked | Boolean | false | 当前是否选中 |
disabled | Boolean | false | 是否禁用 |
color | Color | radio的颜色,同css的color |
代码举例。
wxml
<radio-group bindchange="radioChange">
<radio value='男'>男</radio>
<radio value='女' checked="{{checked}}">女</radio>
</radio-group>
js
/**
* 页面的初始数据
*/
data: {
checked:true
},
radioChange:function(event){
console.log(event.detail)
},
picker
从底部弹起的滚动选择器,现支持五种选择器,通过mode来区分,分别是普通选择器,多列选择器,时间选择器,日期选择器,省市区选择器,默认是普通选择器。
(1)普通选择器-selector
属性名 | 类型 | 默认值 | 说明 | 最低版本 |
---|---|---|---|---|
range | Array / Object Array | [] | mode为 selector 或 multiSelector 时,range 有效 | |
value | Number | 0 | value 的值表示选择了 range 中的第几个(下标从 0 开始) | |
bindchange | EventHandle | value 改变时触发 change 事件,event.detail = {value: value} | ||
disabled | Boolean | false | 是否禁用 | |
bindcancel | EventHandle | 取消选择或点遮罩层收起 picker 时触发 |
代码举例如下。
wxml
<picker
mode="selector"
range="{{array}}"
value='1'
bindchange="onbindchange"
>
<button size='mini' type='primary'>1.普通选择器</button>
</picker>
js
/**
* 页面的初始数据
*/
data: {
array: ['美国', '中国', '巴西', '日本','韩国','巴西','印度','泰国'],
},
/**点击确认时回调 */
onbindchange:function(event){
console.log(event.detail)
},
(2)多列选择器-multiSelector
属性名 | 类型 | 默认值 | 说明 | 最低版本 |
---|---|---|---|---|
range | 二维Array / 二维Object Array | [] | mode为 selector 或 multiSelector 时,range 有效。二维数组,长度表示多少列,数组的每项表示每列的数据,如[["a","b"], ["c","d"]] | |
range-key | String | 当 range 是一个 二维Object Array 时,通过 range-key 来指定 Object 中 key 的值作为选择器显示内容 | ||
value | Array | [] | value 每一项的值表示选择了 range 对应项中的第几个(下标从 0 开始)。[0,0] | |
bindchange | EventHandle | value 改变时触发 change 事件,event.detail = {value: value} | ||
bindcolumnchange | EventHandle | 某一列的值改变时触发 columnchange 事件,event.detail = {column: column, value: value},column 的值表示改变了第几列(下标从0开始),value 的值表示变更值的下标 | ||
bindcancel | EventHandle | 取消选择时触发 | 1.9.90 | |
disabled | Boolean | false | 是否禁用 |
代码举例如下。
wxml
<picker
mode="multiSelector"
range="{{multiArray}}"
value="{{multiIndex}}"
bindcolumnchange="onbindcolumnchange"
bindchange="onbindchange"
>
<button size='mini' type='primary'>2.多列选择器</button>
</picker>
js
/**
* 页面的初始数据
*/
data: {
multiArray: [
['无脊柱动物', '脊柱动物'],
['扁性动物', '线形动物', '环节动物', '软体动物', '节肢动物'],
['猪肉绦虫', '吸血虫']
],
multiIndex: [1, 0, 1],
},
/* 点击确认时回调 */
onbindchange:function(event){
console.log(event.detail)
},
/* 当滚动的时候会回调 */
onbindcolumnchange:function(event){
console.log(event.detail) // {column:0,value:0} 代表是滚动第0列的第0个值
},
(3)时间选择器-time
属性名 | 类型 | 默认值 | 说明 | 最低版本 |
---|---|---|---|---|
value | String | 表示选中的时间,格式为"hh:mm" | ||
start | String | 表示有效时间范围的开始,字符串格式为"hh:mm" | ||
end | String | 表示有效时间范围的结束,字符串格式为"hh:mm" | ||
bindchange | EventHandle | value 改变时触发 change 事件,event.detail = {value: value} | ||
bindcancel | EventHandle | 取消选择时触发 | 1.9.90 | |
disabled | Boolean | false | 是否禁用 |
代码举例如下。
wxml
<picker
mode="time"
value="{{time}}"
start="09:00"
end="21:00"
bindchange="bindTimeChange"
>
<button size='mini' type='primary'>3.时间选择器</button>
</picker>
js
/**
* 页面的初始数据
*/
data: {
time: '12:01',
},
bindTimeChange:function(event){
console.log(event.detail)
},
(4)日期选择器-date
代码举例如下。
wxml
<picker
mode="date"
value="{{date}}"
start="2015-09-01"
end="2017-09-01"
bindchange="bindDateChange"
>
<button size='mini' type='primary'>4.日期选择器</button>
</picker>
js
data: {
date:'2016-01-01'
},
bindDateChange:function(event){
console.log(event.detail)
},
(5)省市区选择器-region
代码举例如下。
wxml
<picker
mode="region"
bindchange="bindRegionChange"
value="{{region}}"
custom-item="{{customItem}}"
>
<button size='mini' type='primary'>5.省市区选择器</button>
</picker>
js
/**
* 页面的初始数据
*/
data: {
region: ['广东省', '广州市', '海珠区'],
customItem: '全部'
},
bindRegionChange: function (event) {
console.log(event.detail)
},
注意:很多属性不是必须的。
picker-view
和picker的区别是,picker-view不是从底部弹出滚动器,而是嵌入页面的滚动器。
注意,该组件中只可放置<picker-view-column/>
组件,其他组件节点不会显示。
value | NumberArray | 数组中的数字依次表示 picker-view 内的 picker-view-column 选择的第几项(下标从 0 开始),数字大于 picker-view-column 可选项长度时,选择最后一项。 | [0,0,0] |
---|---|---|---|
indicator-style | String | 设置选择器中间选中框的样式 | |
indicator-class | String | 设置选择器中间选中框的类名 | 1.1.0 |
mask-style | String | 设置蒙层的样式 | 1.5.0 |
mask-class | String | 设置蒙层的类名 | 1.5.0 |
bindchange | EventHandle | 当滚动选择,value 改变时触发 change 事件,event.detail = {value: value};value为数组,表示 picker-view 内的 picker-view-column 当前选择的是第几项(下标从 0 开始) | |
bindpickstart | EventHandle | 当滚动选择开始时候触发事件 | 2.3.1 |
bindpickend | EventHandle | 当滚动选择结束时候触发事件 |
注意:<picker-view-column/>
仅可放置于 picker-view中,其孩子节点的高度会自动设置成与picker-view的选中框的高度一致。
代码举例如下。
wxml
<picker-view
indicator-style="height: 50px;"
value="{{value}}"
style="width: 100%; height: 300px;background:orange;"
bindchange="bindChange"
>
<picker-view-column>
<view wx:for="{{years}}" style="line-height: 50px;text-align:center">{{item}}年</view>
</picker-view-column>
<picker-view-column>
<view wx:for="{{months}}" style="line-height: 50px;text-align:center">{{item}}月</view>
</picker-view-column>
<picker-view-column>
<view wx:for="{{days}}" style="line-height: 50px;text-align:center">{{item}}月</view>
</picker-view-column>
<picker-view-column>
<view style="line-height: 50px;text-align:center">上午</view>
<view style="line-height: 50px;text-align:center">下午</view>
</picker-view-column>
</picker-view>
js
const date = new Date()
const years = []
const months = []
const days = []
for (let i = 2000; i <= date.getFullYear(); i++) {
years.push(i)
}
for (let i = 1; i <= 12; i++) {
months.push(i)
}
for (let i = 1; i <= 31; i++) {
days.push(i)
}
Page({
/**
* 页面的初始数据
* years [2000,2001,...]
* months [1, 2,...]
* days [1, 2,...]
* value [1,1,1]
*/
data: {
years,
months,
days,
value: [1, 0, 1],
},
bindChange(event) {
console.log(event.detail.value)
}
})
swiper
swiper是一个滑块视图容器,即轮播图组件或者焦点图组件。swiper这个组件封装的已经比较完善,使用起来非常方便。
注意,swiper中只可放置swiper-item组件,否则会导致未定义的行为。
swiper-item的宽度自定义设计为100%。
属性名 | 类型 | 默认值 | 说明 | 最低版本 |
---|---|---|---|---|
indicator-dots | Boolean | false | 是否显示面板指示点 | |
indicator-color | Color | rgba(0, 0, 0, .3) | 指示点颜色 | 1.1.0 |
indicator-active-color | Color | #000000 | 当前选中的指示点颜色 | 1.1.0 |
autoplay | Boolean | false | 是否自动切换 | |
current | Number | 0 | 当前所在页面的 index | |
interval | Number | 5000 | 自动切换每一页时间的间隔 | |
duration | Number | 500 | 滑动一页时的动画时长 | |
circular | Boolean | false | 是否采用衔接滑动( loop ) | |
vertical | Boolean | false | 滑动方向是否为纵向 | |
bindchange | EventHandle | current 改变时会触发 change 事件,event.detail = {current: current, source: source} |
代码举例如下。
wxml
<view>
<swiper style="height:400rpx;background-color:green;"
indicator-dots="true"
indicator-color="white" indicator-active-color="#06C1AE"
autoplay="true" interval="2000"
duration="1000"
circular="true"
vertical="false"
>
<block wx:for="{{banners}}">
<swiper-item>
<image src="{{item}}" style="width:100%;"></image>
</swiper-item>
</block>
</swiper>
</view>
js
Page({
data:{
banners:[
'../../image/TB1y_TAJSrqK1RjSZK9SutyypXa.jpg',
'../../image/TB12OV5B7PoK1RjSZKbSut1IXXa.jpg',
'../../image/TB1OVaZIVzqK1RjSZFCSuvbxVXa.jpg'
],
},
/**
* 生命周期函数-监听页面加载
*/
onLoad:function(options){
}
})
video
视频组件,用来播放本地和网络上的视频 。
属性名 | 类型 | 默认值 | 说明 | 最低版本 |
---|---|---|---|---|
src | String | 要播放视频的资源地址 | ||
initial-time | Number | 指定视频初始播放位置: initial-time='100' 或 initial-time='{{60}}' | 1.6.0 | |
duration | Number | 仅指定视频时长: duration='60' | 1.1.0 | |
controls | Boolean | true | 是否显示默认播放控件(播放/暂停按钮、播放进度、时间)controls="{{true}}" | |
danmu-list | Object Array | 弹幕列表:danmu-list="{{ arr }}" | ||
danmu-btn | Boolean | false | 是否显示弹幕按钮,只在初始化时有效,不能动态变更 | |
enable-danmu | Boolean | false | 是否展示弹幕,只在初始化时有效,不能动态变更 | |
autoplay | Boolean | false | 是否自动播放 | |
loop | Boolean | false | 是否循环播放 | 1.4.0 |
muted | Boolean | false | 是否静音播放 | 1.4.0 |
page-gesture | Boolean | false | 在非全屏模式下,是否开启亮度与音量调节手势 | 1.6.0 |
bindplay | EventHandle | 当开始/继续播放时触发play事件 | ||
bindpause | EventHandle | 当暂停播放时触发 pause 事件 | ||
bindended | EventHandle | 当播放到末尾时触发 ended 事件 | ||
bindtimeupdate | EventHandle | 播放进度变化时触发,event.detail = {currentTime: '当前播放时间'} 。触发频率应该在 250ms 一次 | ||
bindfullscreenchange | EventHandle | 当视频进入和退出全屏是触发,event.detail = {fullScreen: '当前全屏状态'} | 1.4.0 | |
objectFit | String | contain | 当视频大小与 video 容器大小不一致时,视频的表现形式。contain:包含,fill:填充,cover:覆盖 | |
poster | String | 默认控件上的音频封面的图片资源地址,如果 controls 属性值为 false 则设置 poster 无效 |
1)基本使用
代码举例如下。
wxml
<block wx:for="{{urls}}">
<video src="{{item}}" style="width:100%;height:400rpx;"></video>
</block>
js
data:{
urls[
"http://baobab.kaiyanapp.com/api/v1/playUrlvid=56841&...qcloud",
"http://baobab.kaiyanapp.com/api/v1/playUrlvid=56841&...qcloud",
"http://baobab.kaiyanapp.com/api/v1/playUrlvid=56841&...qcloud",
"http://baobab.kaiyanapp.com/api/v1/playUrlvid=56841&...qcloud"
],
}
2)其他属性使用
wxml
<view>
<block wx:for="{{urls}}">
<video src="{{item}}"
style="width:100%;height:400rpx;"
//指定视频初始播放位置 1.6.0
initial-time="100"
muted="{{true}}"
loop="{{true}}"
autoplay="{{true}}"
bindplay="onBindplay"
bindpause="onBindpause"
>
</video>
</block>
</view>
3)弹幕使用
wxml
<view>
<block wx:for="{{urls}}">
<video id="myVideo" src="{{item}}"
style="width:100%;height:400rpx;"
danmu-list="{{danmuList}}"
danmu-btn="true"
enable-danmu="true"
>
</video>
</block>
<input
bindblur="onBindBlur"
placeholder="请输入弹幕:"
style="background-color:#ccc;height:80rpx;">
</input>
<button type="primary" bindtap="sendDanmu">点击发送弹幕</button>
</view>
js
let inputValue = "";
let videoContext = null;
Page({
data:{
danmuList:
[
{
text: '第 1s 出现的弹幕',
color: '#ff0000',
time: 1
},
{
text: '第 3s 出现的弹幕',
color: '#ff00ff',
time: 3
}
],
}
onReady:function(){
// 拿到页面的video实例,赋值给变量
this.videoContext = wx.createVideoContext("myVideo")
}
onBindBlur:function(e){
// 获取input输入框的值,赋值给变量
this.inputValue = e.detail.value
},
sendDanmu:function(){
// 调用video实例的sendMenu方法发送弹幕
this.videoContext.sendMenu({
text: this.inputValue,
color: getRandomColor()
})
}
})
// 随机获取颜色值, 返回的结果例如: #AE0B08
function getRandomColor() {
const rgb = []
for (let i = 0; i < 3; ++i) {
let color = Math.floor(Math.random() * 256).toString(16) // AE、B、8
color = color.length == 1 ? '0' + color : color // AE、0B、08
rgb.push(color)
}
return '#' + rgb.join('') // AE0B08
}
9)模板
在微信小程序中,也可以定义模板来使用。
(1)在wxml页面中定义模版:<template name="abc"> xxxx <template>;
(2)使用模版:<template is="abc" data="{{ }}"> <template>。
代码举例如下。
wxml
<!-- 1.定义模板 -->
<template name="tempName">
<view>
<text>我是一个模板</text>
</view>
</template>
<!-- 2.使用模板 -->
<template is="tempName"/>
还可以动态渲染模板。
wxml
<!-- 1.定义模板 -->
<template name="tempName1">
<view>
<text>我是第1个模板\n</text>
</view>
</template>
<template name="tempName2">
<view>
<text>我是第2个模板\n</text>
</view>
</template>
<!-- 2.使用模板 -->
<template is="{{2>4?'tempName1':'tempName2'}}"/>
模板可以接收参数。
wxml
<!-- 1.定义模板 -->
<template name="tempName1">
<view>
<text>我是第1个模板\n</text>
<!-- 3.接收参数 -->
<text>{{msg}}-->{{time}}</text>
</view>
</template>
<!-- 2.使用模板 data传递参数 -->
<template is="tempName1" data="{{ ...item }}"/>
js
/**
* 页面的初始数据
* 可以在item中定义一个事件的名称传递到模版中
*/
data: {
item: {
msg: 'this is a template',
time: '2018-12-16'
}
},
也可以对模板进行抽取,然后再使用。
步骤:
1)定义外部模版<template name=""> xxxx </template>
2)导入外部模版 <import src="" ></import>
3)使用模版:<template is="" data="{{}}"></template>
可以单独建立一个文件夹,就叫“temp”,然后定义模板:
注意:
模板中的样式一般写在app.wxss文件中;
或者直接写在组件上(内联样式);
也可以写在使用模板的页面上,例如template.wxml使用模板了,则就可以在template.wxss上写样式。
最后在template.wxml里引用模板message.wxml:
<!-- 使用外部的模板 -->
<import src="../temp/message.wxml" />
<template is="tempName3" data="{{...item}}"/>
到此,理解完上述知识点就可以实现基本的开发了。之后会更新另一篇关于案例的博客,届时已经提高到进阶水平。