赵工的个人空间


专业技术部分转网页计算转业余爱好部分


  网站建设

首页 > 专业技术 > 网站建设 > 微信小程序
微信小程序

微信小程序是一种不需要安装即可使用的应用,用户扫一扫或者搜一搜即可打开应用,用完即走。小程序采用了React Native和Weex一样的解析技术,开发者可以编写一套代码在多端运行。小程序其实也是需要下载和安装的,但规定程序包不超过1M,使得下载、安装过程特别快。

1.小程序开发核心:

小程序框架可让开发者在微信中用尽可能简单、高效的方式开发出具有原生App体验的服务,这套框架控制着小程序完整的生命周期,负责页面的加载、渲染、销毁等工作,它是小程序的核心。
小程序框架将整个系统划分为视图层和逻辑层,视图层由框架设计的标签语言WXML(WeiXin Markup Language)和用于描述样式的WXSS(WeiXin Style Sheets)组成,逻辑层是一套运行在本地JavaScript引擎的代码,遵循CommonJS规范。
小程序整体开发流程非常接近HTML+CSS+JavaScript的开发模式,但没有DOM的概念,没有window、document等对象,小程序中的视图层和逻辑层的交互是通过数据绑定和事件响应实现的。

1)小程序的目录结构:

打开微信开发者工具,填写AppId和项目名称,就创建了项目目录。项目目录中包括app.json、app.js、app.wxss三个文件和子目录mypages,mypages子目录下至少有一个index子目录,其中包括index.json、index.wxml、index.js、index.wxss文件。
其中app.json中代码为:
{"pages":["mypages/index/index"]}
运行这个项目时,首先解析app.json,通过pages设置找到默认首页页面mypages/index/index,然后加载mypages/index目录中的index.wxml、index.js、index.wxss、index.json进行页面渲染。

2)框架主体文件:

框架主体文件由app.json、app.js、app.wxss构成,这3个文件必须放置在项目的根目录,一个小程序只有一份,文件名必须为app,分别控制小程序的整体配置、逻辑和整体样式,小程序启动时只会执行一次,其中app.json、app.js是必须的。
·app.json:小程序公共设置,配置小程序全局设置
·app.js:小程序逻辑文件,主要用于注册小程序全局实例,编译时会和其他页面逻辑文件打包成一份JavaScript文件
·app.wxss:小程序公共样式表,对所有页面的布局文件都有效

3)框架页面文件:

一个小程序有一个或多个页面,一个页面由.wxml、.wxss、.js和json四个文件组成,分别控制页面的结构、样式、逻辑和配置,其中.wxml、.js是必须的。同一个页面的这4个文件必须具有相同的路径和文件名,目录名和页面文件名可以不一致,为了便于管理一般保持一致。

4)配置文件app.json:

app.json是小程序配置文件,编写时要严格遵循json格式。app.json在程序加载时加载,负责对小程序的全局配置,配置项有:
·pages:设置页面路径,必填项
·window:设置默认页面的窗口表现
·tabBar:设置tab表现
·networkTimeout:设置网络超时时间
·debug:设置是否开启debug模式,默认关闭
app.json文件内容整体结构为:
{"pages":[],
"window":{},
"tabBar":{},
"networkTimeout":{},
"debug":false}
①pages配置:
pages负责配置注册小程序页面,必须填写,value值为一个包含页面路径的数组,用来指定小程序由哪些页面构成,每一项由页面“路径+文件名”组成。示例:
{"pages":["mypages/index/index","mypages/page2/pagefilename","otherpages/index/index"]}
pages数组中页面路径不需要填写文件名后缀名,路径中的文件名可以与目录名不一致,但为了便于管理,建议文件名和目录名保持一致。
pages配置数组第一项代表小程序的初始页面。小程序中增加、删除页面,都需要对pages数组进行修改,并且重启项目。
②window配置:
window负责设置小程序状态栏、导航条、标题、窗口背景色等系统级样式。属性有:
·navigationBarBackgroundColor:导航栏背景颜色,值为HexColor(16进制颜色值),默认#000000
·navigationBarTextStyle:导航栏标题颜色,仅支持black/white,默认值white
·navigationBarTitleText:导航栏标题文字内容
·backgroundColor:窗口背景色,值为HexColor(16进制颜色值),如#ff83fa,默认#ffffff
·backgroundTextStyle:下拉背景字体、Loading图的样式,仅支持dark/light
·enablePullDownRefresh:是否开启下拉刷新,默认false,开启后当用户下拉时会触发页面onPullDownRefresh事件
③tabBar配置:
当程序顶部或底部需要菜单栏时,可以通过配置tabBar快速实现,这是必填项。配置属性:
·color:tab上的文字默认颜色,值为HexColor(16进制颜色值),必填项
·selectedColor:tab上的文字选中时的颜色,值为HexColor(16进制颜色值),必填项
·backgroundColor:tab背景色,值为HexColor(16进制颜色值),必填项
·borderStyle:tabbar上边框的颜色,仅支持black/white,默认值black
·list:tab的列表,必填项,其值为一个数组,最少2个、最多5个,数组中每一项是一个对象,代表一个tab的相关配置。每项的相关配置为:
·pagePath:页面路径,必须在pages中先定义,必填项
·text:tab上按钮的文字,必填项
·iconPath:tab上icon图片的相对路径,icon大小限制为40kb,必填项
·selectedIconPath:选中时图片的相对路径,icon大小限制为40kb,必填项
·position:tab在顶部或底部显示,可选值bottom/top,默认值bottom
示例:
{"pages":["mypages/index/index","mypages/list/list"],
"tabBar":{"color":"#000000","selectedColor":"#ff7f50","backgroundColor":"#ffffff","borderStyle":"black",
"list":[{"iconPath":"image/home.png","selectedIconPath":"images/home-selected.png","pagePath":"mypages/index/index","text":"首页"},
{"iconPath":"image/search.png","selectedIconPath":"images/search-selected.png","pagePath":"mypages/list/list","text":"搜索"},
{"iconPath":"image/list.png","selectedIconPath":"images/list-selected.png","pagePath":"mypages/list/list","text":"列表"}],
"borderStyle":"bottom"}}
④networkTimeout配置:
小程序中各种网络请求API的超时时间的统一设置。networkTimeout支持的属性有:
·request:设置wx.request的超时时间,单位毫秒
·connectSocket:设置wx.connectSocket的超时时间,单位毫秒
·uploadFile:设置wx.uploadFile的超时时间,单位毫秒
·downloadFile:设置wx.downloadFile的超时时间,单位毫秒
示例:
{"pages":["mypages/index/index"],
"networkTimeout":{"request":60000,"connectSocket":60000}}
⑤debug配置:
控制是否开启debug模式,默认是关闭的。开启debug模式后,在开发者工具的控制面板,调试信息以info形式输出。

5)小程序逻辑app.js:

可以通过App()函数注册小程序生命周期函数、全局方法和全局属性,已注册的小程序实例可以在其他逻辑层代码中通过getApp()获取。
①注册小程序:
App()函数用于注册一个小程序,参数为一个Object对象,在这个参数对象中可以注册自定义方法和属性供全局使用。App()函数必须在app.js中注册,且不能注册多个,参数属性为:
·onLaunch:生命周期函数,监听小程序初始化。当小程序初始化完成,就会触发此事件,只会触发一次。
·onShow:生命周期函数,监听小程序显示。当小程序启动,或从后台进入前台显示时,都会触发此事件。
·onHide:生命周期函数,监听小程序隐藏。当小程序从前台进入后台会触发。
·其他:开发者可以添加任意的函数或数据到Object参数中,这些属性会被注册到小程序对象中,其他逻辑文件可以通过getApp()函数获取已注册的小程序实例。
当启动一个小程序时,首先会依次触发onLaunch和onShow方法,然后通过app.json的pages属性注册相应的页面,最后根据默认路径加载首页;当用户点击左上角关闭,或者按了设备Home按钮离开微信时,小程序并没有直接销毁,而是进入后台,这两种情况都会触发onHide方法;当再次唤醒微信或再次从微信中打开小程序时,又会从后台进入前台,这时会触发onShow方法。只有当小程序进入后台一定时间,或者系统资源占用过高,才会被真正销毁。
注册小程序示例代码:
App({
onLaunch:function(){},
onShow:function(){},
onHide:function(){},
globalFunction:'全局函数',
globalData:'全局属性'});
②获取小程序实例:
注册小程序后,在其他逻辑文件中,可以通过全局函数getApp()获取小程序实例:
var app=getApp();
console.log(app.globeData);
在App()注册的函数中,可以使用this直接获取App实例。通过getApp()获取实例后,可以获取注册的属性、调用注册的方法,但不要私自调用生命周期函数,这样会打乱项目逻辑。

6)全局样式app.wxss:

app.wxss是全局样式表,对项目中每个页面都有效,可将一些系统级别的统一样式风格写入这个文件。页面渲染后,页面的.wxss文件样式会覆盖app.wxss中相同的选择器样式。wxss是小程序基于CSS拓展的一套样式语言,实现了大部分CSS规则。

2.框架页面文件:

小程序中一个框架页面包含4个文件,同一框架页面的这4个文件必须具有相同的路径与文件名,进入小程序时或页面跳转时,小程序会根据app.json配置的路径找到对应的资源进行渲染。

1)页面配置文件.json:

页面配置文件是一个json文件,非必要的,配置项只有window,控制当前页面的窗口表现,其属性与app.json的一致。渲染页面时,页面中的window配置项会覆盖app.json中的相同配置项。
由于页面的.json只能配置window相关属性,编写时只需直接写属性。示例:
{"navigationBarBackgroundColor":"#000000","navigationBarTextStyle":"black","navigationBarTitleText":"myPage","backgroundColor":"#efefef","backgroundTextStyle":"light"}

2)页面逻辑文件.js:

主要功能有设置初始化数据、注册当前页面生命周期函数、注册事件处理函数等。小程序的逻辑层文件是JavaScript文件,所有的逻辑层文件最终会打包成一个js文件,在小程序启动时运行,直到小程序销毁。
在小程序中,每个逻辑文件有独立的作用域,并具备模块化能力。逻辑文件并非在浏览器中运行,浏览器提供的对象,如document、window等,在小程序中都无法使用,而一些基于document、window的框架也都不能在小程序中使用,不能通过操作DOM改变页面,需要转化为数据绑定和事件响应。
①注册页面:
在页面逻辑文件中需要通过Page()函数注册页面,指定页面的初始数据、生命周期函数、事件处理函数等,参数为一个Object对象,属性为:
·data:页面的初始数据,数据格式必须是可转成JSON格式的对象类型。当页面第一次渲染时,data会以JSON格式由逻辑层传至渲染层,渲染层可以通过WXML对数据进行绑定。
·onLoad:生命周期函数,页面加载时触发。一个页面只会调用一次,接受页面参数,可以获取wx.navigateTo、wx.redirectTo以及<navigator/>中的query参数。
·onShow:生命周期函数,页面显示时触发。每次打开页面都会调用一次。
·onReady:生命周期函数,页面初次渲染完成时触发。一个页面的生命周期中只会调用一次,代表当前页面已经准备妥当,可以和视图层进行交互。一些对界面的设置,操作需要在页面准备妥当后调用,如wx.setNavigationBarTitle需要在onReady后设置。
·onHide:生命周期函数,页面隐藏时触发。
·onUnload:生命周期函数,页面卸载时触发。
·onPullDownRefresh:页面处理函数,用户下拉时触发。需要将app.json配置中window的enablePullDownRefresh属性设置为true。当处理完数据刷新后,可以调用wx.stopPullDownRefresh方法停止当前页面的下拉刷新。
·onReachBottom:页面上拉触底事件的处理函数。
·其他:开发者可以添加任意的函数或数据到Object参数中,可以用this访问这些函数和数据。
示例:
var app=getApp();
Page({
data:{count:0}, //页面初始化数据
onLoad:function(){}, //页面加载时执行
onShow:function(){}, //页面打开时执行
onReady:function(){}, //页面初次渲染完成后执行,一个页面只会调用一次
onHide:function(){}, //页面隐藏时执行
onUnload:function(){}, //页面卸载时执行
onPullDownRefresh(){}, //下拉刷新时执行
onReachBotton:function(){}, //下拉触底时执行
countClick:function(){ //自定义函数,可与组件进行事件绑定
this.setData({count:this.data.count+1});
},
customData:{name:'微信'} //自定义数据
});
页面的生命周期函数复杂一些:
·小程序初始化:默认页面入栈,依次触发默认页面onLoad、onShow、onReady方法
·打开新页面:新页面入栈,依次触发新页面onLoad、onShow、onReady方法
·页面重定向:当前页面出栈并卸载,触发当前页面onUnload方法,新页面入栈,触发新页面onLoad、onShow、onReady方法
·页面返回:页面不断出栈并卸载,触发当前弹出页面onUnload方法,直到返回目标页面,新页面入栈,触发新页面onShow方法
·Tab切换:当前页面出栈但不卸载,仅触发onHide方法,新页面入栈,如果当前页面是新加载的,触发onLoad、onShow、onReady方法,如果当前页面已加载过,仅触发onShow
·程序从前台到后台:触发当前页面onHide方法,触发App onHide方法
·程序从后台到前台:触发小程序onShow方法,触发页面onShow方法
总体上,页面在生命周期中只会触发onShow和onLoad方法,只有加载和卸载时才会触发onLoad、onReady和onUnload方法,而触发页面卸载只有页面返回和页面重定向两种操作。
②获取当前页面栈:
getCurrentpages()函数用于获取当前页面栈的实例,页面栈以数组形式按栈顺序给出,第一个元素为首页,最后一个元素为当前页面。示例:
var pages=getCurrentPages();
var currentPage=pages[pages.length-1];
③事件处理函数:
页面对象中注册的函数可以和视图层中的组件进行绑定,当达到触发条件时,就会执行Page中定义的相应事件,这类自定义函数统称为事件处理函数,小程序中组件的事件分为通用事件和特殊事件。示例:
<view bindtap="myevent">点击执行逻辑层事件</view>
Page({myevent:function(){console.log('点击了view');}});
④触发视图层渲染:
页面首次加载时,框架会结合初始化数据渲染页面,在逻辑层需要主动调用Page.protptype. setData()方法。当Page.protptype.setData()被调用,会将数据从逻辑层发送到视图层触发绘图重绘,同时会修改Page的data值。setData()接受一个Object对象参数,方法会自动将this.data中的key对应的值变成Object参数中的key对应的值。当Object参数key对应的值和this.data中key对应的值一致时,将不会触发视图层渲染。
Object参数的key值非常灵活,可以按数据路径的形式给出,如array[5].info、obj.key.subkey。
示例:
<view>{{text}}</view>
<button bindtap="changeText">修改普通数据</button>
<view>{{object.subObject.objectText}}</view>
<button bindtap="changeObjectText">修改对象数据</button>
<view>{{array[0].arrayText}}</view>
<button bindtap="changeArrayText">修改数组数据</button>
<view>{{newField.newFieldText}}</view>
<button bindtap="addNewData">添加新字段</button>
Page({
data:{
text:'normal data',
object:{subObject:{objectText:'object data'}},
array:[{arrayText:'array data'}],
changeText:function(){this.setData({text:'new normal data'});},
changeObjectText:function(){this.setData({'object.subObject.objectText':'new object data'});},
changeArrayText:function(){this.setData({'array[0].arrayText':'new array data'});},
addNewData:function(){this.setData({'newField.newFieldText':'add new data'});}
});
⑤页面生命周期:
页面生命周期关系着页面视图层线程和页面逻辑层线程,注册页面时,Object参数中很多属性都是生命周期函数,这些函数的调用和页面生命息息相关。
线程启动后,视图层和逻辑层相互监听,当逻辑层线程触发onLoad、onShow方法后会把初始数据data传送给视图层线程,视图层完成第一次渲染后触发逻辑层onReady方法,之后就可以通过setData方法主动触发视图层渲染。当页面被调往后台时,触发onHide方法,这时逻辑层线程并没有销毁,仍然可以通过代码控制视图层渲染,只是不会在界面上表现出来。当页面从后台回到前台时,触发onShow方法,最后当页面销毁时,触发onUnload方法。

3)页面结构文件WXML:

WXML是框架设计的一套标记语言,用于渲染页面。WXML语言最终会转译为宿主端对应的语言,只能使用小程序定义的标记,不能自定义,以保证页面被正确转译。WXML具有数据绑定、列表渲染、条件渲染、模板、事件等能力。
①数据绑定:
小程序中页面渲染时,框架会将WXML文件同对应的Page的data进行绑定,页面中可以直接使用data中的属性。小程序数据绑定使用双大括号将变量或简单的运算规则包起来。有几种主要方式:
⑴简单绑定:
简单绑定是指使用双大括号将变量包起来,在模板中直接作为字符串输出使用,可作为内容、组件属性、控制属性、关键字等输出,其中关键字输出是指将JavaScript中的关键字按其真值输出。示例:
<view>{{content}}</view> <!--作为内容-->
<view id="item-{{id}}" style="border:{{border}}">作为组件属性渲染</view>
<view wx:if="{{showContent}}">作为控制属性渲染</view>
<view>{{2}}</view>
<checkbox checked="{{false}}"></checkbox> <!--关键字-->
Page({data:{border:'solid 1px #000',id:1,content:'内容',showContent:false}});
组件属性为boolean类型时,一定要使用关键字输出checked="{{false}}"。
⑵运算:
在{{}}内可以做一些简单运算,支持的运算有三元运算、算术运算、逻辑判断、字符串运算,符合JavaScript规则。示例:
<view>{{showContent?'显示文本':'不显示文本'}}</view>
<view>{{num1+num2}}+1+{{num3}}=?</view>
<view>{{"name:"+name}}</view>
<view>{{num3>0}}</view>
<view>{{myObject.age}}{{myArray[1]}}</view>
Page({data:{showContent:false,num1:1,num2:2,num3:3,name:'weixin',
myObject:{age:12},myArray:['arr1','arr2']}});
⑶组合:
data中的数据可以在模板再次组合成新的数据结构,这种组合常常在数组或对象中使用。
数组组合比较简单,可以直接将值放置到数组某个下标下:
<view>{{[myValue,2,3,'stringtype']}}</view>
Page({data:{myValue:0}});
最终页面组合成对象为[0,2,3,'stringType']。
对象组合有3种组合方式,以数据注入模板为例。
第一种:直接将数据作为value值进行组合
<template is="testTemp" data="{{name:myValue1,age:myValue2}}"></template>
Page({data:{myValue:'value1',myValue2:'value2'}});
最终组合出的对象为:{name:'value1',age:'value2'}
第二种:通过“...”将一个对象展开,把key-value值复制到新的结构中
<template is="testTemp" data="{{...myObj1,key5:5,...myObj2,key6:6}}"></template>
Page({data:{myObj1:{key1:1,key2:2},myObj2:{key3:3,key4:4}}});
最终组合出的对象为:{key1:1,key2:2,key5:5,key3:3,key4:4,key6:6}
第三种:如果对象key值和value相同,可以只写key值
<template is="testTemp" data="{{key1,key2}}"></template>
Page({data:{key1:1,key2:2}});
最终组合出的对象为:{key1:1,key2:2}
②条件渲染:
⑴wx:if:
除了简单的数据绑定,常常还需要使用逻辑分支,这时可以使用wx:if="{{判断条件}}"来进行条件渲染,当条件成立时渲染该代码块。示例:
<view wx:if="{{showContent}}">内容</view>
Page({data:{showContent:false}});
示例中view代码将不会渲染,只有当showContent的值为true时才渲染。
WXML也支持wx:elif和wx:else,必须与wx:if配合使用,否则会解析出错。示例:
<view wx:if="{{false}}">1</view>
<view wx:elif="{{false}}">2</view>
<view wx:else>3</view>
⑵block wx:if:
wx:if是一个控制属性,可以添置在任何组件标记上,如果需要包装多个组件,又不想影响布局,就需要使用<block/>标记将需要包装的组件放置在里面,通过wx:if作判断。<block/>并不是一个组件,仅仅是一个包装元素,示例:
<block wx:if="{{true}}">
<view>view组件</view>
<image/>
</block>
⑶wx:if与hidden:
除了wx:if组件,也可以通过hidden属性控制组件是否显示,二者的区别:
·wx:if控制是否渲染,当其条件值切换时会触发局部渲染或销毁,频繁切换时会产生消耗
·hidden控制组件是否渲染,组件始终会被渲染,只是简单控制显示与隐藏,并不会触发重新渲染和销毁
③列表渲染:
⑴wx:for:
组件的wx:for控制属性用于遍历数组,重复渲染该组件,遍历过程中当前项的下标变量名默认为index,数组当前项变量名默认为item。示例:
<view wx:for="{{myArray}}">{{index}}:{{item}}</view>
Page({data:{myArray:['value1','value2']}});
通过遍历myArray,页面渲染了两个<view/>。
⑵wx:for-index和wx:for-item:
index、item变量名可以通过wx:for-index、wx:for-item属性修改。示例:
<view wx:for="{{myArray}}" wx:for-index="myIndex" wx:for-item="myitem"> {{myIndex}}:{{myItem:name}}</view>
Page({data:{myArray:[{name:'value1'},{name,'value2'}]}});
普通遍历中没必要修改index、item变量名,当wx:for嵌套使用时,就有必要设置变量名,避免变量名冲突。示例:
<view wx:for="{{myArray}}" wx:for-index="myIndex" wx:for-item="myitem"> <block wx:for="{{myItem}}" wx:for-index="subIndex" wx:for-item="subItem">{{subItem}} </block> </view>
Page({data:{myArray:[[1,2,3],[4,5,6],[7,8,9]]}});
wx:for也可以直接在<block/>标记上使用,以渲染一个包含多个节点的结构块。
④模板:
项目中,常常需要遇到某些相同的结构在不同的地方反复出现,这时可以将相同的布局代码片段放置到一个模板中,在不同的地方传入对应的数据进行渲染,这样能避免重复开发,提升开发效率。
⑴定义模板:
在<template/>内定义代码片段,设置其中的name属性,指定模板名称即可。示例:
<template name="myTemplate">
<view>内容</view>
<view>{{content}}</view>
<view>{{name}}</view>
<view>{{myObj.key1}}</view>
<view>{{key2}}</view>
</template>
⑵使用模板:
使用模板时,设置is属性指向需要使用的模板,设置data属性,将模板所需的变量传入。模板拥有自己的作用域,只能使用data属性传入的数据,而不是直接使用Page中的data数据,渲染时<template/>标记将被模板中的代码块完全替换。示例:
<template is="myTemplate" data="{{content:'',name,myObj,...myObj2}}"/>
Page({data:{name:'myTemplate',myObj:{key1:'value1'},myObj2:{key2:'value2'}}});
模板is属性支持数据绑定,在项目过程中可以通过属性绑定动态决定使用哪个模板。如:
<template is="{{templateName}}" data="myData"/>
⑶模块的嵌套使用:
<template name="bTemplate">
<view>b template content</view>
</template>
<template name="aTemplate">
<view>a template content</view>
<template is="bTemplate"/>
</template>
<template is="aTemplate"/>
⑤事件:
WXML中的事件系统也是通过在组件上设置“bind+事件名”属性进行事件绑定,当触发事件时,框架会调用逻辑层中对应的事件处理函数,并将当前状态通过参数传递给事件处理函数。小程序中没有DOM节点,事件只能通过WXML绑定,不能通过逻辑层动态绑定。
⑴事件分类:
事件分为冒泡事件和非冒泡事件。
·冒泡事件:当一个组件上的事件被触发后,该事件会向父节点传递
·非冒泡事件:当一个组件上的事件被触发后,该事件不会向父节点传递
WXML冒泡事件有:touchstart、touchmove、touchcancel、touchend、tap、longtap,对于冒泡事件,每个组件都是默认支持的,其他如无特殊声明都是非冒泡事件。
⑵事件绑定:
事件绑定的写法和组件的属性一样,以key、value形式组织。
·key:以bind或catch开头,然后跟上事件类型,字母均小写,如bindtap、catchtouchstart
·value:事件函数名,对应Page中定义的同名函数
绑定时,bind不会阻止冒泡事件向上冒泡,catch会阻止冒泡事件向上冒泡。示例:
<view bindtap="tap1">view1
<view catchtap="tap2">view2
<view bindtap="tap3">view3</view>
</view>
</view>
⑶事件对象:
当组件触发事件时,逻辑层绑定该事件的事件处理函数会收到一个事件对象。示例:
<view bindtap="myevent">view</view>
Page({myevent:function(e){console.log(e);}});
代码中的参数e就是事件对象,代码执行后事件对象输出为:
{"type":"tap","timeStamp":6571,
"target":{"id":"","offsetLeft":0,"offsetTop":0,"dataset":{}},
"currentTarget":{"id":"","offsetLeft":0,"offsetTop":0,"dataset":{}},
"detail":{"x":15,"y":11},
"touches":[{"identifier":0,"pageX":15,"pageY":11,"clientX":15,"clientY":11}],
"changedTouches":[{"identifier":0,"pageX":15,"pageY":11,"clientX":15,"clientY":11}]}
⑷事件对象的属性:
事件对象的属性可分为三类:BaseEvent、CustomEvent、TouchEvent
其中BaseEvent为基础事件对象属性,包括:
·type:事件类型
·timeStamp:事件生成时的时间戳,页面打开到触发所经过的毫秒数
·target:触发事件源组件(即冒泡开始的组件)的相关属性集合,其中,id为事件源组件的id,tagName为事件源组件的类型,dataset为事件源组件上由data-开头的自定义属性组成的集合
·currentTarget:事件绑定的当前组件的相关属性集合,其中,id为当前组件的id,tagName为当前组件的类型,dataset为当前组件上由data-开头的自定义属性组成的集合
<canvas/>中的触摸事件不可冒泡,所以没有currentTarget。dataset是组件的自定义数据,通过这种方式可以将组件的自定义属性传递给逻辑层,书写方式为以data-开头多个单词由连字符“-”连接,属性名不能有大写,最终在dataset中将连字符转成驼峰形式。示例:
<view bindtap="myevent" data-my-name="weixin" data-myAge="12">dataset</view>
Page({myevent:function(e){console.log(e.currentTarget.dataset);}});
最后dataset打印出来为:
{"myName":"weixin","myage":"12"}
连字符被转成驼峰,大写字母都被转为小写字母。
CustomEvent为自定义事件对象,继承BaseEvent,只有一个属性:
·detail:额外信息,通常传递组件特殊信息,具体见组件相关文档
TouchEvent为触摸事件对象,继承BaseEvent,属性有:
·touches:触摸事件,当前停留在屏幕中的触摸点信息的数组
·changedTouches:触摸事件,当前变化的触摸点信息的数组
由于支持多点触摸,所以touches和changedTouches都是数组格式,每一个元素为一个Touch对象(canvas触摸事件为CanvasTouch对象)。
Touch对象相关属性为:
·identifier:触摸点的标识符
·pageX和pageY:距离文档左上角的距离
·clientX和clientY:距离页面可显示区域(屏幕除去导航条)左上角的距离
⑥引用:
一个WXML可以通过import或include引入其他WXML文件,import引入文件后只接受模板的定义,忽略模板定义外的所有内容,使用过程中有作用域的概念;include则是将引入文件中除<template/>以外的代码直接复制到<include/>位置。也就是,import更适合引入模板定义文件,include更适合引入组件文件。
⑴import:
<import/>的src属性是需要被引入文件的相对地址,<import/>引入会忽略引入文件中<template/>定义以外的内容。
<import src="b.wxml">
<template is="bTemplate" data="" />
import引用有作用域概念,只能直接使用引入的定义模板,而不能使用间接引入的定义模板。
⑵include:
include引入会将模板定义标记外的内容直接复制替换<include/>
<include src="b.wxml">

4)页面样式文件WXSS:

WXSS是基于CSS拓展的样式语言,具有CSS的大部分特性,用于描述WXML组件样式。开发过程中一定要开启开发者工具中“开启上传代码时样式自动补全”功能,这样小程序会自动补全其余一些样式的兼容性写法,保证在不同终端达到统一视觉效果。
①尺寸单位:
CSS原有尺寸单位在不同尺寸屏幕中不能完美实现元素按比例缩放,WXSS拓展了rpx和rem两种单位,都是相对单位,最终会换算为px。
·rpx:WXSS规定屏幕宽度为750rpx
·rem:WXSS规定屏幕宽度为20rem
由于rpx和rem最终要被换算为px,某些情况下可能会存在除不尽情况,导致界面中产生毛刺,需要多测试来避免。
②选择器:
WXSS实现了CSS的部分选择器:


选择器

样例

描述

.class

.myClassName

选择所有拥有class="myClassName"的组件

#id

#myIdName

选择所有拥有id="myIdName"的组件

element

view

选择所有view组件

element,element

view,checkbox

选择所有文档的view组件和所有checkbox组件

::after

view::after

在view组件后面插入内容

::before

view::before

在view组件前面插入内容

选择器示例:
.myClass{border:solid ipx #000;}
view.myClass{border:solid ipx #000;}
.myContent radiobox{border:solid ipx #000;}
view.myClass::after{content:'new content'}
③内联样式:
可以通过style、class属性控制样式。一般静态样式可以统一写到class中,style样式会在运行时解析。尽量避免将静态样式写入style,以免影响渲染速度。示例:
<view style="border:solid ipx #000;background-color:{{color}}"></view>
<view class="myClassName1 myClassName"></view>
④样式导入:
通常在项目中为了便于管理,将WXSS按职责拆分为多个文件,这时需要@import语句在当前WXSS文件中导入其他WXSS文件:
.common-view{border:solid 1px #000;}
@import "common.wxss";
.page-container{padding:10px;}

5)模块化:

模块化主要解决JavaScript中命名冲突和文件依赖问题,一般都遵循或接近CommonJS规范。
模块是一段JavaScript代码,具有统一的基本书写格式,模块之间通过基本交互规则能彼此引用,协同工作。目前模块化规范大致可分为CommonJS和ES6两种规范。
①文件作用域:
小程序中一个JavaScript文件就是一个模块,在这个文件中声明的变量和函数只在该文件中有效,不同文件中的相同变量名和函数名不会互相影响。模块中可以调用一些全局的方法。
var appData=getApp();
appData.myGlobalData.name+='app';
②模块的使用:
模块通过exports暴露接口,通过require(path)引入依赖,path是需要引入的模块文件的相对路径。示例:
module.exports.run=run;
exports.walk=walk;
或者:
module.exports={run:run,walk:walk};
引入:
var otherMod=require('mod.js');
Page({onShow:function(){otherMod.run('somebody');otherMod.walk('somebody');}});

3.布局:

WXSS实现了CSS布局相关的大部分规范,但在一些细节上有差异,在代码编写过程中一定要开启开发者工具中的“开启上传代码时样式文件自动补全”功能,否则会出现不同终端兼容性问题。

1)盒子模型:

盒子模型是CSS布局的基础,其中假定每个元素都会生成一个或多个矩形框,每个元素框中心都有一个内容区content,这个内容区周围有内边距padding、边框border、外边距margin,这些项默认宽度为0,这个矩形框就是常说的盒子模型。
小程序中每个组件就是一个盒子,元素的宽度、高度就是内容区宽度、高度,可以通过元素width、height、padding、border、margin属性控制盒子样式。WXSS完全遵守W3C盒子模型规范。
CSS布局都是基于盒子模型,不同类型元素对盒子模型的处理不同,块级元素的处理就和行内元素不同,浮动元素和定位元素的处理也不同。

2)块级元素:

元素按显示方式主要分为块级元素和行内元素,元素的显示方式是由display属性控制,块级元素会默认占一行高度,一般一行内只有一个块级元素(浮动后除外),当再添加新的块级元素时会自动换行显示。块级元素一般作为容器出现,用于组织结构。
一些元素默认就是块级元素,如小程序中的<view/>组件,对默认的行内元素可通过修改元素display属性为block,强制设置为块级元素。一个块级元素的元素框与其父元素的width相同,块级元素的width+marginLeft+marginRight+paddingLeft+paddingRight刚好等于父级元素内容区宽度,显示时默认撑满父元素内容区。块级元素高度由其子元素决定,父级元素高度会随内容元素变化而变化。示例:
<view style="border:solid 1px;margin:10px;padding:10px;"></view>

3)行内元素:

行内元素和其他非块级元素都在一行上,其高度、宽度、上下margin、上下padding设置均无效,只能设置左右margin和左右padding。行内元素宽度就是文字或图片宽度,不能直接设置宽度和高度,内部只能容纳文本或其他行内元素,不能放置块级元素。
小程序中<text/>就是一个行内元素,也可以通过设置display属性为inline可以将一个块级元素设置为行内元素。示例:
<view style="border:solid 1px;margin:10px;padding:0 10px;display:inline;"></view>

4)行内块元素:

是块级元素和行内元素的混合物,当display属性为inline-block时,元素就被设置为一个行内块元素。行内块元素可以设置宽、高、内边距和外边距。示例:
<view style="border:solid 1px;margin:10px;padding:10px;display:inline-block"></view>
注意行内块元素宽度撑满父级元素与行内块元素宽度不足父级元素两种情况下的外观差别。

5)浮动:

通过设置float属性,浮动的框可以向左或右移动,直到其外边缘碰到包含框或另一个浮动的边框为止。由于浮动框不在文档的普通流中,文档其他内容会环绕过去。示例:
<view style="display:block;float:left;border:solid 1px;margin:20px;">浮动框</view>
由于元素浮动不在普通流中,会导致父级元素忽略浮动元素高度,形成坍塌。有些情况下,希望在浮动的同时父级元素的高度能包裹浮动元素,需要使用clear属性。当设置元素clear时,可以确保当前元素的左边、右边或左右两边不能出现浮动的元素。示例:
<view style="border:solid 1px;">
<view>元素1</view>
<view style="float:left;">浮动框</view>
<view style="clear:left;">清除浮动元素</view>
</view>
实际项目中,为了复用性和便捷性,通常使用.clearfix类,在WXSS中使用after伪属性:
<view style="border:solid 1px;margin-top:10px;" class="clearfix">
<view>元素1</view>
<view style="float:left;">浮动框</view>
</view>
WXSS文件中:
.clearfix:after {display:block;height:0;clear:both;content:''}

6)定位:

元素的定位由position属性控制。position有4种不同类型的定位:
·static:元素框正常生成。块级元素生成一个矩形框,作为文档流的一部分,行内元素则会创建一个或多个行框,置于其父元素中,static是position的默认值。
·relative:元素框偏移某个距离。元素仍保持其未定位前的形状,原本所占的空间仍保留。
·absolute:元素框从文档流中完全删除,并相对于其包含块定位,包含块可能是文档中的另一个元素或者是初始包含块。包含块是离当前元素最近的position为absolute或relative的父元素,如果父元素中没有任何absolute或relative布局的元素,那么包含块就是根元素。
·fixed:元素框的表现类似于将position设置为absolute,不过其包含块是视窗本身。
使用position布局后,元素原先在正常流中所占用的空间会关闭,就好像该元素原来不存在一样。元素定位后生成一个块级框,不论原来它在正常流中生成何种类型的框。示例:
<view style="border:solid 1px;position:relative;height:80px;">
<text style="position:absolute;left:10px;bottom:10px;">absolute</text>
</view>

7)flex布局:

2009年W3C提出了一种新的Flex布局方案,可以简单快速地完成各种伸缩性的设计。Flex是Flexible Box的缩写,即为弹性盒子布局,可以为传统盒子模型带来更大的灵活性,目前主流浏览器都支持这种布局。
Flex布局主要由容器和项目构成,采用Flex布局的元素,称为Flex容器,它的所有直接子元素自动成为容器成员,称为Flex项目。可以设置display:flex或display:inline-flex将任何一个元素指定为Flex布局。
容器默认存在两根轴,水平的主轴(main axis)和垂直的交叉轴(cross axis),主轴开始的位置(主轴与边框的交叉点)称main start,结束的位置称main end;交叉轴开始的位置称cross start,结束的位置称cross end。项目默认沿主轴,从主轴开始的位置到主轴结束的位置进行排列,项目在主轴上占据的空间称main size,在交叉轴上占据的空间称cross size。
①容器的属性:
容器支持的属性有display、fiex-direction、flex-wrap、flex-flow、justify-content、align-items、align-content等。
⑴display:
用来指定该元素是否为Flex布局:
.mybox{display:flex|inline-flex;}
其中,flex用于产生块级Flex布局;inline-flex用于产生行内flex布局。设置Flex布局后,子元素的float、clear和vertical-align属性将会失效。
⑵flex-direction:
用于指定主轴的方向,即项目排列的方向:
.mybox{flex-direction:row|row-reverse|colum|colum-reverse;}
其中,row设置主轴为水平方向,起点在左端,是默认值;row-reverse设置主轴为水平方向,起点在右端;colum设置主轴为垂直方向,起点在上沿;colum-reverse设置主轴为垂直方向,起点在下沿。
⑶flex-wrap:
默认情况下,项目都排列在一条线上,flex-wrap用来指定如果一条轴排不下去应怎样换行:
.mybox{flex-wrap:nowrap|wrap|wrap-reverse;}
其中,nowrap为不换行,是默认值;wrap为换行,第一行在上方;wrap-reverse为换行,第一行在下方。
当设置换行时,还需要设置align-item属性配合实行自动换行,并且align-item的值不能为stretch。
⑷flex-flow:
flex-flow是flex-direction和flex-wrap的简写形式,默认值为row nowrap。语法为:
.mybox{flex-flow:<flex-direction>||<flex-wrap>;}
示例:
.mybox{flex-flow:row-reverse wrap;}
.mybox{flex-flow:wrap;}
⑸justify-content:
定义了项目在主轴上的对齐方式:
.mybox{justify-content:flex-start|flex-end|center|space-between|space-around;}
其中,flex-start为左对齐,是默认值;flex-end为右对齐;center为居中;space-between为两端对齐,项目之间的间隔都相等;space-around为每个项目两侧的间隔相等,所以项目之间的间隔比项目与边框的间隔大一倍。
⑹align-items:
指定项目在交叉轴上如何对齐:
.mybox{align-items:flex-start|flex-end|center|baseline|stretch;}
align-items与交叉轴方向有关。flex-start为交叉轴的起点对齐;flex-end为交叉轴的终点对齐;center为交叉轴的中线对齐;baseline为项目根据它们第一行文字的基线对齐;stretch为如果项目未设置高度或设置为auto,项目将在交叉轴方向拉伸填充整个容器,是默认值。
⑺align-content:
用来定义项目多根轴线(出现换行后)在交叉轴上的对齐方式,如果项目只有一根轴线,该属性不起作为:
.mybox{align-content:flex-start|flex-end|center|space-between|space-around|stretch;}
其中,flex-start为与交叉轴的起点对齐;flex-end为与交叉轴的终点对齐;center为与交叉轴的中点对齐;space-between为与交叉轴两端对齐,轴线之间的间隔平均分布;space-around为每根轴两侧的间隔都相等,轴线之间的间隔比轴线与边框间隔大一倍;stretch为轴线占满整个交叉轴,每个项目会被拉伸直至填满交叉轴,默认值。
②项目属性:
项目支持的属性有order、flex-grow、flex-shrink、flex-basis、flex、align-self等。
⑴order:
定义项目的排列顺序,数值越小,排列越靠前,默认为0:
.myitem{order:<integer>;}
⑵flex-grow:
定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大:
.myitem{flex-grow:<number>;}
如果所有项目的flex-grow值都为1,则它们将等分剩余空间。如果一个项目的flex-grow属性为2,其他项目都为1,则前者占据的剩余空间将比其他项多一倍,整体按比例填充剩余空间。
⑶flex-shrink:
定义了项目的缩小比例,默认为1,如果空间不足,该项目将缩小:
.myitem{flex-shrink:<number>;}
如果使用项目的flex-shrink属性都为1,当空间不足时,都将等比缩小;如果一个项目的flex-shrink属性为0,其他项目都为1,则空间不足时,前者不缩小,负值对该属性无效。
⑷flex-basic:
用来定义伸缩项目的基准值,剩余空间将按比例进行缩放,默认值为auto,即项目的本来大小:
.myitem{flex-basic:<length>|auto;}
可以设为跟width或height属性一样的固定值,如320px,这样项目将占据固定空间。
⑸flex:
flex属性是flex-grow、flex-shrink和flex-basic的缩写,默认值为0 1 auto:
.myitem{none|[<'flex-grow'><'flew-shrink'>?||<'flex-basic'>]}
建议优先使用这个属性,而不是单独写三个分离的属性。示例:
.myitem{flex:1 1 auto}
.myitem{flex:auto}
.myitem{flex:0 0 auto}
.myitem{flex:none}
.myitem{flex:1 auto;}
.myitem{flex:1 1 auto}
.myitem{flex:1 1;}
⑹align-self:
用来设置单独的伸缩项目在交叉轴上的对齐方式,该属性会复写默认的对齐方式:
.myitem{align-self:auto|flex-start|flex-end|center|baseline|stretch;}
其中,auto表示继承容器align-items属性,如果没有父元素,则等同于stretch,是默认值;flex-start表示交叉轴的起点对齐;flex-end表示交叉轴的终点对齐;center表示交叉轴的中线对齐;baseline表示项目根据它们第一行文字的基线对齐;stretch表示如果项目未设置高度或设置为auto,项目将在交叉轴方向拉伸填充整个容器,是默认值。

4.组件:

小程序定义了各种组件,在WXML中起着各不相同的作用。组件是指从组件开始标记到结束标记的所有代码,属性用来修饰这个组件,内容在两个标记之内。由于组件可能会被转译为不同端对应的代码,所以不能使用小程序组件标记以外的标记。
组件是视图层的基本组成单元,自带一些功能与微信风格的样式。组件按类型划分为视图容器、基础内容、表单、导航、多媒体、地图、画布等七大类。组件结构为:
<tagname property="value">contents</tagname>
组件可以通过属性进行配置,一个组件可以对应多个属性,属性有名称和值两部分。组件的属性名都是小写,可以使用连字符,分为共同属性和自定义属性。
组件的共同属性指每个组件都有的属性,在每个组件中代表的意义和作用一样。
·id:组件的唯一表示,保持整个页面唯一。
·class:组件的样式类,对应WXSS中定义的样式
·style:组件的内联样式,可以动态设置的内联样式
·hidden:主机是否显示,所有组件默认显示
·data-*:自定义属性,组件上触发事件时,会发送给事件处理函数
·bind*/catch*:组件的事件,绑定逻辑层相关事件处理函数,bind为冒泡事件,catch为非冒泡事件
每个属性都有其对应的类型,使用时应给属性值传入对应的类型值,属性类型可分为Boolean、Number、String、Array、Object、EventHandler、Any。组件上写上该属性,不管该属性等于什么,其值都为true,只有组件上没有写该属性时,属性值才为false。

1)视图容器:

小程序中,有类似<div/>的容器组件,就是<view/>、<scroll-view/>、<swiper/>。容器组件内部能嵌套任何标记,是构建布局的基础组件。
①view组件:
块级容器组件,主要用于布局展示,是布局中最基本的UI组件,任何复杂的布局都可以通过嵌套<view/>组件,配合相关WXSS实现。
<view/>组件具备关于点击行为的属性:
·hover:是否启动点击态,默认值为false
·hover-class:指定按下去的样式。当hover-class="none"时没有点击态效果,默认为none
·hover-start-time:按住后多久出现点击态,单位毫秒,默认为50
·hover-stay-time:手指松开后点击态保留时间,单位毫秒,默认为400
示例:常用的布局方式
⑴水平3栏布局
<view style="display:flex;">
<view style="background-color:red;flex-grow:1;height:80rpx;">1</view>
<view style="background-color:blue;flex-grow:1;height:80rpx;">2</view>
<view style="background-color:green;flex-grow:1;height:80rpx;">3</view>
</view>
⑵左右混合布局:
<view style="display:flex;height:400rpx">
<view style="background-color:red;width:250rpx;color:#fff;">1</view>
<view style="flex-grow:1;display:flex;flex-direction:column;">
<view style="flex-grow:1;background-color:blue;color:#fff;">2</view>
<view style="flex-grow:1;background-color:green;color:#fff;">3</view>
</view>
</view>
⑶上下混合布局:
<view style="display:flex;flex-direction:column;height:400rpx">
<view style="background-color:red;height:250rpx;color:#fff;">1</view>
<view style="flex-grow:1;display:flex;">
<view style="flex-grow:1;background-color:blue;color:#fff;">2</view>
<view style="flex-grow:1;background-color:green;color:#fff;">3</view>
</view>
</view>
②scroll-view:组件:
布局中需要一些容器有可滑动能力,需要<scroll-view/>组件。属性为:
·scroll-x:允许横向滚动,默认false
·scroll-y:允许纵向滚动,默认false
·upper-threshold:距顶部/左边多远时(单位px)触发scrolltoupper事件,默认50
·lower-threshold:距底部/右边多远时(单位px)触发scrolltolower事件,默认50
·scroll-top:设置竖向滚动条位置
·scroll-left:设置横向滚动条位置
·scroll-into-view:值应为某子元素id,滚动到该元素时,元素顶部对齐滚动区域顶部
·bindscrolltoupper:滚动到顶部/左边,会触发bindscrolltoupper事件
·bindscrolltolower:滚动到底部/右边,会触发bindscrolltolower事件
·bindscroll:滚动时触发,
event.detail={scrollLeft,scrollTop,scrollHeight,scrollWidth,deltaX,deltaY}
目前,有些组件不能在<scroll-view/>组件中使用,包括<textarea/><video/><map/><convas/>。
示例:创建一个纵向滚动区域,并监听其滚动事件
<scroll-view class="scroll-container" upper-threshold="0" lower--threshold="100"
scroll-into-view="{{toView}}" bindscroll="scroll" bindscrolltolower="scrollToLower"
bindscrolltoupper="scrollToUpper" scroll-y="true" scroll-top="{{scrollTop}}">
<view id="item-1" class="scroll-item bg-red">1</view>
<view id="item-2" class="scroll-item bg-blue">2</view>
<view id="item-3" class="scroll-item bg-red">3</view>
<view id="item-4" class="scroll-item bg-blue">4</view>
<view id="item-4" class="scroll-item bg-red">5</view>
<view id="item-6" class="scroll-item bg-blue">6</view>
</scroll-view>
<view class="act"><button bindtap="scrollToTop">点击滚动到顶部</button></view>
WXSS:
.scroll-container{border:solid 1ps;height:800rpx;}
.scroll-container .scroll-item{height:300rpx;width:120%;}
.bg-blue{background-color:#87cefa;}
.bg-red{background-color:#ff6347;}
.act{padding:10px;}
Page({data:{toView:'item-3'},
scrollToUpper:function(){console.log('触发滚动到顶部事件');},
scrollToLower:function(){console.log('触发滚动到底部事件');},
acroll:function(){console.log('触发了滚动事件');},
scrollToTop:function(){this.setData({scrollTop:'0'});}});
在使用纵向滚动时,需要先给<scroll-view/>一个固定高度。
③滑块视图组件:
利用滑块视图容器可以实现轮播图、滑动页面、图片预览效果。一个完整的滑块视图组件由<swiper/>和<swiper-item/>两个标记组成,一个<swiper/>中只能放置一个或多个<swiper-item/>,放置其他节点会被删除。<swiper-item/>内部可以放置任何组件,默认宽高自动设置为100%。<swiper-item/>组件没有任何属性,只是一个容器。<swiper/>组件属性有:
·indicator-dots:是否显示面板指示点,默认为false
·autoplay:是否自动切换,默认为false
·current:当前所在页面的index,默认为0
·interval:自动切换时间间隔,默认为5000
·duration:滑块动画时长,默认为1000
·circular:是否采用衔接滑动,默认为false
·bindchange:current改变时 会触发change事件,event.detail={current:current}
示例:简单轮播图
<swiper class="banner" indicator-dots="true" autoplay="{{autoplay}}" current="0"
interval="2000" duration="300" bindchange="change">
<block wx:for="{{sliderList}}">
<swiper-item class="{{item.className}}">{{item.name}}</swiper-item>
</block>
</swiper>
<view><button bindtap="play">暂停|播放</button></view>
.banner{height:400px;background-color:#ddd;}
.bg-blue{background-color:#87cefa;}
.bg-red{background-color:#ff6347;}
.bg-green{background-color:#43cd80;}
Page({data:{autoplay:true,
{sliderList:[{className:'bg-red',name:'slider1'},
{className:'bg-blue',name:'slider2'},
{className:'bg-green',name:'slider3'}]},
play:function(){this.setData({autoplay:!this.data.autoplay});},
change:function(){console.log('执行了滚动');}});
示例2:自定义轮播图
<swiper/>默认组件不提供面板指示点的样式设置,需要时可以通过bindchange事件实现。
<view class="customSwiper">
<swiper class="banner" autoplay=true interval="2000" duration="300"
bindchange="switchTab">
<block wx:for="{{sliderList}}">
<swiper-item>
<image style="width:100%;height:100%;" src="{{item.imageSource}}"/>
</swiper-item>
</block>
</swiper>
<view class="tab">
<block wx:for="{{sliderList}}">
<view wx:if="{{item.selected}}" class="tab-item selected">{{index+1}}</view>
<view wx:else class="tab-item">{{index+1}}</view>
</block>
</view>
</view>
.customSwiper{height:379.5rpx;position:relative;}
.customSwiper swiper{height:100%;}
.tab{height:70rpx;position:absolute;bottom:0;display:flex;width:100%;text-align:center;justify-content:center;align-items:center;}
.tab .tab-item{background-color:#ccc;height:50rpx;width:50rpx;line-height:50rpx;font-size:12rpx;color:#fff;border-radius:4px;margin-right:10px;}
.tab .tab-item.selected{background-color:red;}
Page({data:{
{sliderList:[{selected:true,imageSource:'./image/banner1.jpg'},
{selected:false,imageSource:'./image/banner2.jpg'},
{selected:false,imageSource:'./image/banner3.jpg'}]},
switchTab:function(e){var slidederList=this.data.sliderList,i,1;
for(i=0;item=sliderList[i];++i)
{item.selected=e.detail.current==i;}
this.setData({sliderList:sliderList});}});

2)基础组件:

①icon:
<icon/>是页面中非常常用的组件,通常用于表示状态,起到引导作用。微信官方提供了一套规范的样式类型,当然也可以通过自定义样式创建自定义图标。<icon/>的属性有:
·type:icon的类型,有效值包括success、success_no_circle、info、warn、waiting、cancel、download、search、clear。
·size:icon大小,单位px,默认值23px
·color:icon的颜色,与CSS相同
示例:
<icon type="success_no_circle" size="{{item}}"/>
项目中常常会用到自定义UI风格,需要自定义样式的<icon/>组件:
<icon class="myicon home"/>
.myicon{background:url(./image/icons.jpg) no-repeat;background-size:1100rpx 826rpx;
width:60rpx;height:60rpx;}
.myicon.home{background-position:-520rpx -90px;}
开发过程中应尽量使用小程序提供的系统样式,这能保证小程序在微信系统中UI风格的一致性。
②text组件:
<text/>组件主要用于文本内容的展示,类似HTML中的<p/>标记。小程序中,只有<text/>节点内部的内容能被长按选中。<text/>是行内元素,除了组件共同属性外没有提供其他属性,组件内只支持<text/>嵌套,以实现某些字符加粗、标红等特殊样式。文本内容支持转义字符“\”,如“\n”、“\t"。示例:
<text>{{content}}</text>
Page({data:{content:'文本内容\t可以使用转义字符\n'}});
③progress组件:
<progress/>用于显示进度状态,比如资源加载、用户资料完成度、媒体播放器进度等。<progress/>是块级元素,属性有:
·percent:当前进度占所有进度的百分比,取值区间0~100
·show-info:是否在进度条右侧显示百分比,默认false
·stroke-width:进度条线的宽度,单位px,默认值为6
·color:进度条颜色,默认值#09bb7
·active:渲染时是否开启进度条从左到右的动画,默认false
示例:
<progress percent="20" stroke-width="10" color="#cd5555"></progress>

3)表单组件:

表单是应用中获取用户输入的重要手段,用户在应用中输入的大部分内容都是在表单中完成的。表单组件不仅可以放置在<form/>标记中使用,同时也可以作为单独组件和其他组件混合使用。
⑴radio组件:
单选项可以用来生成一组单选按钮,供用户从一批固定的选项中作出选择。小程序中单选框由<radio-group/>和<radio/>两个组件组合而成,一个包含多个<radio/>的<radio-group/>表示一组单选项,在同一组单选项中的<radio/>是互斥的,当一个按钮被选中,之前选中的按钮就变为非选中。
在小程序中,<radio/>不能单独使用,同一组<radio/>包含在<radio-group/>中,这样才能形成一组单项选择按钮,<radio/>的选中态不能直接获取,需要通过<radio-group/>的change事件获取。<radio-group/>内部除了包含<radio/>也可以其他标记,当包含其他标记时也仅仅对标记内部的<radio/>产生影响,而不影响其他组件。<radio-group/>仅有一个属性:
·bindchange:绑定<radio-group/>的change事件,当其中的选中项发生变化时触发
event.detai={value:选中项radio的value}
<radio/>是<radio-group/>中的一个单选按钮,具有以下属性:
·value:<radio/>标识。当该<radio/>选中时,<radio-group/>的change事件会携带<radio/>的value
·checked:当前<radio/>是否选中,默认为false。一个<radio-group/>只能有一个<radio/>的checked为true,如果设置多个将默认选中最后一个为true的单选项。
·disabled:是否禁用,禁用后不能点击,默认为false。
·color:radio的颜色,与CSS相同。
示例:
<radio-group bindchange="changeChoosed">
<view wx:for="{{radio}}">
<radio value="{{item.value}}" checked="{{item.checked}}"/>{{item.text}}
</view>
</radio-group>
Page({data:{radios:[
{value:'1',text:'选项1',checked:false},
{value:'2',text:'选项2',checked:true},
{value:'3',text:'选项3',checked:false},
{value:'4',text:'选项4',checked:false}]},
changeChoosed:function(event){console.log('你选中了:'+event.detail.value);});
一般选项按钮需要使用<label/>配合使用。
⑵checkbox组件:
小程序的复选框也是由<checkbox-group/>和<checkbox/>两个组件组合而成。一个包含多个<checkbox/>的<checkbox-group/>表示一组多选项,一组多选项允许在待选项中选中一项以上的选项。
<checkbox-group/>用于包裹<checkbox/>,而且仅有一个属性bindchange。<checkbox-group/>中的选中项发生变化时触发change事件,event.detail={value:[选中项checkbox的value数组]}。
<checkbox/>是<checkbox-group/>中的一个多选项目,它的属性和<radio/>一样:
·value:<checkbox/>标识,<checkbox/>选中时触发<checkbox-group/>的change事件,并携带<checkbox/>的value
·checked:当前<checkbox/>是否选中,可用来设置默认值,一个<checkbox-group/>允许一个或多个<checkbox/>的checked为true,默认为false
·disabled:是否禁用,禁用后不能点击,默认为false
示例:
<checkbox-group bindchange="checkboxChange">
<view wx:for="{{countrys}}">
<checkbox value="{{item.value}}" checked="{{item.checked}}"
disabled="{{item.disabled}}"/>{{item.name}}
</view>
</checkbox-group>
Page({data:{countrys:[
{name:'中国',value:'1'},
{name:'美国',value:'2',checked:true},
{name:'日本',value:'3',disabled:true},
{name:'韩国',value:'4'}]},
checkboxChange:function(e){console.log('你选中的项目有:'+e.detail.value);});
选中状态切换时change方法传入的参数是一个数组。
⑶switch组件:
<switch/>是一个可以在两种状态切换的开关选择器,功能上和<checkbox/>接近,但只是单独控件,属性包括:
·checked:是否选中,默认false
·type:<switch/>的UI样式,有效值switch、checkbox,默认switch
·bindchange:checked改变时触发change事件,event.detail={value:checked}
示例:
<view wx:for="{{list}}">
<switch data-name="{{tiem.name}}" type="{{item.type}}" checked="{{item.checked}}"
bindchange="{{item.changeEventName}}"/>
</view>
Page({data:{switchs:[
{name:'switch1',checked:false,type:'switch',changeEventName:'change'},
{name:'switch2',checked:true,type:'checkbox',changeEventName:'change'}]},
change:function(e){
var name=e.currentTarget.dataset.name,
switchs=this.data.switchs,i,s;
for(i=0;s=switchs[i];++i){
if(s.name==name){s.checked=e.detail.value;break;}}
console.log(name+'的选中态为:'+e.detail.value);}
});
⑷label组件:
可以利用<label/>改进表单组件的可用性,通过绑定for属性让用户点击<label/>时触发对应的控件,目前可以绑定的控件有<button/>、<checkbox/>、<radio/>、<switch/>。
小程序中<label/>的触发规则有两种:将控件放在标记内,当用户点击时触发<label/>中第一个控件;设置<label/>的for属性,当用户点击时触发for属性对应的控件。
<label/>只有一个for属性,绑定控件的id。示例:
<view class="section">
<checkbox-group>
<label for="mycheckbox">
<checkbox/>
<checkbox/>
</label>
<checkbox id="mycheckbox"/>
<checkbox-group/>
<view>
⑸slider组件:
滑动选择器是一种在移动端常用的交互组件。小程序中可以利用<slider/>快速生成滑动选择器。滑动选择器一般有水平和垂直两种,但小程序只提供了水平形式,左边是最小值,右边是最大值。属性包括:
·min:最小值,默认值为0
·max:最大值,默认值为100
·step:步长,取值必须大于0,并且可被(max-min)整除,默认为1
·disabled:是否禁用,默认false
·value:当前取值,默认值为0,值应在max和min区间范围,设置后滑块会滚到对应位置
·color:背景条的颜色,默认值#e9e9e9
·selected-color:已选择的颜色,默认值#1aad19
·show-value:是否在右侧显示当前value
·bindchange:完成一次拖动后触发的事件,event.detail={value:value}
示例:使用slider调整图标的大小和透明度
<view class="section icon-wrapper">
<icon type="success" size="{{icon.size}}" style=""opacity:{{icon.opacity/10}};"/>
</view>
<view class="section">
<view>调整图标大小:</view>
<slide show-value max="100" min="10" step="5" value="{{icon.size}}"
bindchange="changeSize"></slider>
</view>
<view class="section">
<view>调整透明度:</view>
<slide show-value max="10" min="0" step="1" value="{{icon.opacity}}"
bindchange="changeOpacity"></slider>
</view>
.section{padding:10px;}
.section.icon-wrapper{height:100px;font-size:12px;}
Page({data:{icon:{size:20,opacity:8}),
changeSize:function(e){
this.data.icon.size=e.detail.value;
this.setData(this.data);},
changeOpacity:function(e){
this.data.icon.opacity=e.detail.value;
this.setData(this.data);},
]);
滑动选择器在移动端的交互体验优于字符输入,项目中数值输入项都可以考虑使用其来替代。
⑹picker组件:
<picker/>可以在屏幕底部弹出一个窗口,供用户在所提供的选择项中选择一个。<picker/>本身不会向用户呈现任何特殊效果,用于包裹其他组件,点击<picker/>包裹内的元素时会从底部弹出相应选项。<picker/>分为普通选择器、时间选择器、日期选择器3种,默认是普通选择器,可以通过设置<picker/>组件的mode属性值切换不同选择器。
◆普通选择器:
这是默认的滚动选择器,只需要绑定数组类型的数据就能直接使用,对应的mode属性值为selector。普通选择器有如下属性:
·range:底部弹出选项的数组,默认为一个空数组,只有当mode为seletor时此属性有效
·rang-key:当range是一个Object Array时,通过rang-key来指定Object中key的值作为选择器的显示内容
·value:mode为seletor时,value值是数字,表示选择了range中的第几个,从0开始
·bindchange:value改变时触发change事件,event.detail={value:value}
·disabled:是否禁用,默认值为false
示例:
<picker value="{{selectedIndex}}" range="{{list}}" bindchange="{{change}}">
<view class="picker">当前选中:{{list[selectedIndex]}}</view>
</picker>
.picker{border:solid 1px #ddd;background-color:#fafafa;padding:10px;}
Page({data:{list:['选项1','选项2','选项3'],selectedIndex:0),
change:function(e){this.setData({selectedIndex:e.detail.value});}});
◆时间选择器:
对应的mode属性为time,有如下属性:
·value:表示选中的时间,字符串格式为“hh:mm”,默认为空
·start:表示有效时间范围的开始,字符串格式为“hh:mm”,默认为空
·end:表示有效时间范围的结束,字符串格式为“hh:mm”,默认为空
·bindchange:value改变时触发change事件,event.detail={value:value}
·disabled:是否禁用,默认值为false
示例:
<picker value="{{selectedTime}}" mode="time" start="{{startTime}}" end="{{endTime}}"
bindchange="{{change}}">
<view class="picker">当前选中:{{selectTime}}</view>
</picker>
.picker{border:solid 1px #ddd;padding:10px;}
Page({data:{startTime:"00:00",endTime:"24:00",selectedTime:"11:30"),
change:function(e){this.setData({selectedTime:e.detail.value});}});
◆日期选择器:
对应的mode属性为date,有如下属性:
·value:表示选中的日期,字符串格式为“yyyy-MM-dd”,默认为0
·start:表示有效日期范围的开始,字符串格式为“yyyy-MM-dd”
·end:表示有效日期范围的结束,字符串格式为“yyyy-MM-dd”
·fields:表示选择器的粒度,有效值为year、month、day,默认为day
·bindchange:value改变时触发change事件,event.detail={value:value}
·disabled:是否禁用,默认值为false
示例:
<picker value="{{selectedDate}}" mode="date" start="{{startDate}}" end="{{endDate}}"
fields="day" bindchange="{{change}}">
<view class="picker">当前选中:{{selectDate}}</view>
</picker>
.picker{border:solid 1px #ddd;padding:10px;}
Page({data:{startDate:"2017-03-01",endDate:"2017-12-31",selectedDate:"2017-07-17"),
change:function(e){this.setData({selectedDate:e.detail.value});}});
⑺picker-view组件:
小程序提供了<picker-view/>组件,可以插入数列,同时也能设置其样式,用于实现自定义滚动选择器。一个完整的<picker-view/>包含<picker-view/>和<picker-view-column/>,其中的<picker-view-column/>用于创建列,<picker-view/>只能放置<picker-view-column/>。属性有:
·value:数组类型,数组中的数字依次表示<picker-view/>内的<picker-view-column/>选择的第几项,下标从0开始,数字大于<picker-view-column/>可选项长度时,选择最后一项。
·indicator-style:设置选择器中间选中框的样式
·bindchange:当滚动选择,value改变时触发change事件,event.detail={value:value},其中value为数组,表示picker-view内的picker-view-column当前选择的是第几项
示例:配送时间选择器
<view class="custom-picker">
<view class="title">自定义滑动选择器</view>
<picker-view indicator-style="height:80px;" bindchange="changeTime">
<picker-view-column>
<view class="cell" wx:for="{{list}}" wx:key="index">{{item.date}}</view>
</picker-view-column>
<picker-view-column>
<block wx:for="{{list}}" wx:key="{{index}}" wx:if="{{item.selected}}">
<view class="cell" wx:for="{{item.times}}" wx:for-index="subIndex"
wx:for-item="subItem" wx:key="subIndex"> {{item.time}}</view>
</block>
</picker-view-column>
</picker-view>
</view>
.custom-picker{top:100px;width:80%;margin:0 auto;margin-top:200rpx;border:solid 1px #ccc;}
.custom-picker .title{text-align:center;color:#444;padding:20px;font-size:24rpx;background-color: #eee;border-bottom:solid 1px #ccc}
.custom-picker picker-view{height:200px;}
.custom-picker picker-view .cell{text-align:center;line-height:80px;}
.custom-picker picker-view-column{border-right:solid 1px #ccc;position:relative;left:1px;}
Page({data:{list:[
{date:'12月27日',selected:true,
times:[{time:'19:00'},{time:'19:30'},{time:'20:00'},{time:'20:30'},{time:'21:00'},
{date:'12月28日',selected:false,
times:[{time:'9:00'},{time:'9:30'},{time:'10:00'},{time:'10:30'},{time:'11:00'},
{date:'12月29日',selected:false,
times:[{time:'12:00'},{time:'12:30'},{time:'13:00'},{time:'14:30'},{time:'15:00'}]},
changeTime:function(e){
var index=e.detail.value[0],list=this.data.list,i,d;
for(i=0;d=list[i];++i){d.selected=i==index?true:false;}
this.setData(this.data)}});
⑻input组件:
<input/>是单行输入框,用于收集用户信息。根据不同的type属性值,输入字段拥有很多形式,都是与输入相关的类型,没有按钮类型。属性比较多:
·value:输入框的初始内容
·type:inout类型,有效值为text、number、idcard、digit、time、date
·password:是否显示密码类型,默认false
·placeholder:输入框为空时的占位符
·placeholder-style:指定placeholder的样式
·placeholder-class:指定placeholder的样式类,默认值input-placeholder
·disabled:是否禁用,默认为false
·maxlength:最大输入长度,设置为0时不限制最大长度,默认140
·cursor-spacing:指定光标与键盘的距离,单位为px。设置后取input距离底部的距离和cursor-spacing指定的距离的最小值作为光标与键盘的距离
·auto-focus:自动获取焦点,拉起键盘。页面中只能有一个<input/>或<textarea/>设置auto-focus属性
·focus:获取焦点,默认为false
·bindinput:当键盘输入时,触发input事件,event.detail={value:value},处理函数可以直接return一个字符串,将替换输入框的内容
·bindfocus:输入框获取焦点时触发,event.detail={value:value}
·bindblur:输入框失去焦点时触发,event.detail={value:value}
·bindconfirm:点击完成按钮时触发,event.detail={value:value}
示例:
<view class="section">
<input placeholder="内容中123会被替换为0" bindinput="changeValue" type="number"
maxlength="20"/>
</view>
.section{font-size:12px;padding:10px 5px;border-bottom:dashed 1px #cecece;}
.section input{border:solid 1px #ccc;padding:0 5px;background-color:#fff;
border-radius:4px;height:30px;}
Page({changeValue:function(e){console.log(e.detail);
var value=e.detail.value,pos=e.detail.cursor,left;
if(pos!=-1){left=value.slice(0,pos);pos=left.replace(/123/g,'2').length;}
return{value:e.detail.value.replace(/123/g,'2'),cursor:pos}}});
⑼textarea组件:
<textarea/>是多行输入框,在小程序中是一个自闭合标记,值需要赋值给value。属性有:
·value:输入框的初始内容
·placeholder:输入框为空时的占位符
·placeholder-style:指定placeholder的样式
·placeholder-class:指定placeholder的样式类,默认值textarea-placeholder
·disabled:是否禁用,默认为false
·maxlength:最大输入长度,设置为0时不限制最大长度,默认140
·auto-focus:自动获取焦点,拉起键盘。页面中只能有一个<input/>或<textarea/>设置auto-focus属性
·focus:获取焦点,默认为false
·auto-height:是否自动增高,设置auto-height时,style.height不生效,初始状态默认为一行高度
·fixed:如果textarea是在一个position.fixed的区域,需要显示指定属性fixed为true,默认为false
·cursor-spacing:指定光标与键盘的距离,单位为px,默认为0。设置后取input距离底部的距离和cursor-spacing指定的距离的最小值作为光标与键盘的距离
·bindinput:当键盘输入时,触发input事件,event.detail={value:value},函数的返回值并不会反映到textarea上
·bindinput:除了date/time类型外的输入框,当键盘输入时,触发input事件,event.detail={value:value,cursor:光标位置},处理函数可以直接return一个字符串,替换输入框的内容
·bindfocus:输入框获取焦点时触发,event.detail={value:value}
·bindblur:输入框失去焦点时触发,event.detail={value:value}
·bindlinechange:输入框行数变化时调用,首次渲染时也会触发,event.detail={height:0, heightRpx:0,lineCount:0}
·bindconfirm:点击完成按钮时触发,event.detail={value:value}
示例:失焦时打印出当前输入内容
<view class="section">
<textarea placeholder="请输入文案" bindblur="getValue"
placeholder-class="textarea-holder"/>
</view>
.section{font-size:12px;padding:10px 5px;border-bottom:dashed 1px #cecece;}
.section textarea{border:solid 1px #ccc;padding:5px;background-color:#fff;
border-radius:4px;height:50px;}
Page({getValue:function(e){console.log(e.detail);}});
注意:不要在scroll-view中使用<textarea/>;<textarea/>的blue事件会晚于页面上的tap事件,如果需要在button的点击事件获取<textarea/>,可以使用<form/>的bindsubmit事件;不建议在多行文本上对用户的输入进行修改,所以<textarea/>的bindinput处理函数并不会将返回值反映到<textarea/>上。
⑽button组件:
按钮除了在应用中提供交互功能,按钮的颜色也承载了应用的引导作用。通常,在一个程序中一个按钮至少有默认点击default、建议点击primary、谨慎点击warn等3种状态,在构建项目时注意在合适的场景使用合适的按钮。当<button/>被<form/>包裹时,可以通过设置form-type属性触发表单对应的事件,<button/>组件除了系统定制的几种类型,也可以通过在标记中嵌套其他组件实现自定义按钮。属性有:
·size:表示按钮的大小,有效值default、mini,默认值default
·type:按钮的样式类型,有效值为primary、default、warn,默认值default
·plain:按钮是否镂空,背景色透明,默认值false
·disable:是否禁用,默认值false
·loading:名称前是否带loading图标,默认false。通常在表单提交过程中,或者按钮点击后等待反馈时,需要打开loading让用户知晓
·form-type:用于<form/>组件,有效值为submit、reset,点击一个位于<form/>中且设置了form-type的<button/>时,会触发<button/>的submit事件或reset事件
·hover-class:指定按钮按下去的样式类。当hover-class="none"时,没有点击态效果,默认值为button-hover。button-hover的默认样式为{background-color:rgba(0,0,0,0.1);opacity:0.7},如果想进行系统级修改可以直接覆盖这个样式
·hover-start-time:按钮后多久出现点击态,单位毫秒,默认值50
·hover-stay-time:手指松开后点击态保留时间,单位毫秒,默认400
<button/>的大部分属性都和样式有关,一些属性外的特殊样式可以通过设置WXSS来实现。示例:
<button size="mini">size:mini</button>
<button type="primary">type:primary</button>
<button loading>loading button</button>
<button><image src="http://img.zcool.cn/community/01923678cdef.gif"/></button>
<button hover-class="my-button-hover">hover-class</button>
.my-button-hover{background-color:red;color:#fff;}
⑾form组件:
<form/>用于嵌入其他表单组件,使之形成表单。当触发<form/>的submit方法时,<form/>能将组件内的用户输入的<switch/>、<input/>、<checkbox/>、<slide/>、<radio/>、<picker/>数据按组件name属性进行组装,作为参数传递给submit方法。通过这种方式,可以利用<form/>方便地获取表单数据同后台进行交互。<form/>属性有:
·report-submit:是否返回formId,formId用于发送模板消息,默认false
·bindsubmit:携带form中的数据触发的submit事件,与form-type属性配合使用
event.detail={value:{'name':'value'},formId:''}
·bindreset:表单重置时触发reset事件,与form-type属性配合使用
示例:点击提交按钮后控制台打印出用户输入项
<form bindsubmit="submit" nindreset="reset">
<view class="section">
<view class="title">switch</view>
<switch name="myswitch"/>
</view>
<view class="section">
<view class="title">input</view>
<switch name="myinput" placeholder="请输入内容" value="{{textvalue}}"/>
</view>
<view class="section">
<view class="title">checkbox</view>
<checkbox-group name="mycheckbox">
<label><checkbox value="1"/>中国</label>
<label><checkbox value="2"/>美国</label>
<label><checkbox value="3"/>日本</label>
</checkbox-group>
</view>
<view class="section">
<view class="title">slider</view>
<slider name="myslider" show-value/>
</view>
<view class="section">
<view class="title">radio</view>
<radio-group name="myradio">
<label>
<radio value="0"/>男
<radio value="1"/>女
</label>
</radio-group>
</view>
<view class="section">
<view class="title">picker</view>
<picker value="{{index}}" range="{{times}}" bindchange="changePicker"/>
<view>时间:{{times[index]}}</view>
</picker>
</view>
<view class="section">
<button type="primary" form-type="submit">提交</button>
<button form-type="reset">重置</button>
</view>
</form>
.section{font-size:12px;padding:10px;border-top:solid 1px #eee;}
.section input{border:solid 1px #ccc;border-radius:4px;}
.section button{margin-bottom:10px;}
.section label{margin-right:20px;}
.section .title{margin:5px 0;}
Page({data:{times:['20:00','20:30','21:00','21:30','22:00'],index:3},
changePicker:function(e){this.setData({index:e.detail.value});},
submit:function(e){console.log(e.detail.value);},
reset:function(e){console.log('已经重置对象')}]);

4)导航组件:

<navigator/>是小程序中的页面链接,作用与HTML中的超链接一样,主要控制页面的跳转。链接内容可以是一个字、词或词组,也可以为一幅图,点击这些内容来跳转到新页面。属性:
·url:应用内跳转链接,链接地址为需要跳转页面的相对地址
·redirect:跳转行为是否为重定向,如果为true则跳转时会关闭当前页面,默认false
·open-type:可选值navigate、redirect、switchTab,对应于wx.navigateTo、wx.redirectTo、wx.switchTab功能,默认值为navigate
·hover-class:点击时的样式,当hover-class="none"时没有点击效果,默认navigator-hover。
navigator-hover默认为{background-color:rgba(0,0,0,0.1);opacity:0.7},<navigator/>子节点背景色应为透明色。
页面间跳转可以通过url进行参数传递,规则符合URL协议,新页面可以通过注册onLoad方法获取参数,也可以通过redirect和url的配合实现刷新当前页面。示例:
<navigator url="../receive/receive?name=weixin app&time=2016">跳转到其他页面</navigator>
receive页面通过注册onLoad事件获取传入的参数:
<view>name:{{query.name}},age:{{query.time}}</view>
Page({data:{query:{}],
onLoad:function(query){this.data.query=query;this.setData(this.data);}});

5)媒体组件:

①image:
应用中图片是必不可少的,小程序提供了<image/>组件,不仅可以显示图片,还提供了图片裁剪、缩放属性。<image/>默认宽度300px,默认高度225px,属性为:
·src:图片资源地址,可以是网络地址,也可以是本地图片的相对地址
·mode:图片的裁剪、缩放模式,默认scaleToFill
·binderror:当错误发生时,发布App Service的事件名,事件对象为event.detail ={errMsg: 'something wrong'}
·bindload:当图片载入完毕时,发布App Service的事件名,事件对象event.detail ={height: '图片高度px',width:'图片宽度px'}
mode模式属性有13种,4种是缩放模式
·scaleToFill:不保持纵横比缩放图片,使图片宽高完全拉伸至填满image元素
·aspectFit:保持纵横比缩放图片,使图片的长边能完全显示出来
·aspectFill:保持纵横比缩放图片,只保证图片的短边能完全显示出来
·widthFix:宽度不变,高度自动变化,图片原有的高度样式会失效
mode模式属性有9种裁剪模式:
·top:不缩放图片,只显示图片的顶部区域
·bottom:不缩放图片,只显示图片的底部区域
·center:不缩放图片,只显示图片的中间区域
·left:不缩放图片,只显示图片的左边区域
·right:不缩放图片,只显示图片的右边区域
·top left:不缩放图片,只显示图片的左上边区域
·top right:不缩放图片,只显示图片的右上边区域
·bottom left:不缩放图片,只显示图片的左下边区域
·botton right:不缩放图片,只显示图片的右下边区域
②audio:
小程序运行的页面中直接嵌入音频组件。属性为:
·src:要播放音频的资源地址,可以是网络音频地址或本地音频文件针对路径
·loop:是否循环播放,默认值flase
·controls:是否显示默认控件,默认true
·poster:默认控件上的音频封面的图片资源地址,如果controls属性值为false则poster无效
·name:默认控件上的音频名字,如果controls属性值为false则name无效,默认为“未知音频”
·author:默认控件上的作者名字,如果controls属性值为false则author无效,默认为“未知作者”
·binderror:当方式错误时触发error事件,detail={errMsg:MediaError.code}
MediaError.code有以下类型:MEDIA_ERR_ABORTED获取资源被用户禁止、MEDIA_ERR _NETWORK网络错误、MEDIA_ERR_DECODE解码错误、MEDIA_ERR_SRC_NOT_SUPPORTTED不适合资源
·bindplay:当开始/继续播放时触发play事件
·bindpause:当暂停播放时触发pause事件
·bindtimeupdate:当播放进度改变时触发timeupdate事件,detail={currentTime,duration}
·bindended:当播放到末尾时触发ended事件
示例:
<audio poster="{{myaudio.poster}}" src="{{myaudio.src}}" name="{{myaudio.name}}"
author="{{myaudio.author}}" controls loop action="{{myaudio.action}}">
</audio>
Page({data:{myaudio:{
src:'./resource/qilixiang.mp3',poster:'http://www.yoka.com/dna/pics/bal/42/d389.jpg',
name:'七里香',author:'周杰伦'}}});
③video:
小程序中允许嵌入视频,默认宽度300px、高度225px。属性为:
·src:要播放视频的资源地址
·controls:是否显示默认播放控件,包括播放/暂停按钮、播放进度、时间等,默认true
·danmu-list:弹幕列表
·danmu-btn:是否显示弹幕按钮,只在初始化时有效,不能动态变更,默认false
·enable-danmu:是否展示弹幕,只在初始化时有效,不能动态变更,默认false
·autoplay:是否自动播放,默认false
·bindplay:当开始/继续播放时触发play事件
·bindpause:当暂停播放时触发pause事件
·bindended:当播放到末尾时触发ended事件
·bindtimeupdate:当播放进度改变时触发timeupdate事件,detail={currentTime,duration},触发频率应250ms一次
·objectFit:当视频大小与video容器大小不一致时,视频的表现形式,属性值包括contain包含、fill填充、cover覆盖,默认contain
示例:
<view class="video">
<video id="myVideo" src="{{src}}" danmu-list="{{danmu}}" enable-danmu controls></video>
<view class="action">
<button bindtap="getVideo">获取视频</button>
<view class="danmu">
<input type="text" value="{{danmuText}}" bindblur="setInputValue"/>
<button bindtap="sendDanmu">发送弹幕</button>
</view>
</view>
</view>
.video video{width:100%;height:562.5rpx;}
.video .action{padding:20rpx;}
.video .action .danmu{margin-top:10px;position:relative;padding-right:210rpx;height:80rpx;}
.video .action .danmu input{border:solid 1px #ccc;height:80rpx;padding:0 10rpx; border-radius:3px;}
.video .action .danmu button{width:200rpx;position:absolute;right:0;bottom:0;height:80rpx;}
Page({data:{src:'http://wxsnsdy.tc.qq.com/105/20120/snsdyvideodownload?filekey=29383',
danmu:[{text:'第1s出现的弹幕',color:'#ff0000',time:1},
{text:'第2s出现的弹幕',color:'#00ff00',time:2}}],danmuText:''},
onReady:function(){this.videoContext=wx.createVideoContext('myVideo');},
getVideo:function(){var self=this;
success:function(res){self.setData({maxDuration:60,src:res.temFilePath});}});},
setInputValue:function(e){this.setData({danmuText:e.detail.value});},
sendDanmu:function(){var danmuText=this.data.danmuText;console.log(this.videoContext);
this.videoContext.sendDanmu({text:danmuText,color:'#ff0000'});
this.setData({danmuText:''});}});
<video/>组件不能在<scroll-view/>中使用。

6)地图组件:

移动应用中地图是必不可少的内容,小程序提供了<map/>组件和定位相关的API。小程序不能使用<map/>以外的地图插件。
小程序中的<map/>组件主要负责地理位置信息的简单展示,具备绘制图标、线路、半径等能力,<scroll-view/>中不能使用<map/>。其属性有:
·latitude:中心纬度
·longitude:中心经度
·scale:缩放级别,默认16
·markers:标记点,用于在地图上显示标记位置,不能自定义标记点的图标和样式。每个标记点有属性,id--标记点id,marker点击事件回调返回此id;latitude--纬度,浮点数,-90~90,必填;longitude--经度,浮点数,-180~180,必填;title--标记点名;iconPath--显示的图标,项目目录下的图片路径,必填;rotate--旋转角度,顺时针旋转的角度,0~360,默认0;alpha--标注的透明度,默认1,不透明;width--标注图标宽度,默认为图片实际宽度;height--标注图标高度,默认为图片实际高度。
·polyline:路线,指定一系列坐标点,从数组第一项至最后一项,数组元素的属性包括,points--经纬度数组,[{latitude:0,longitude:0}],必填;color--线的颜色,8位16进制表示,后两位为alpha,如#000000aa;width--线的宽度;dottedLine--是否为虚线,默认false。
·circles:圆,数组类型,在地图上显示圆,数组元素属性包括,latitude--纬度,浮点数,-90~90,必填;longitude--经度,浮点数,-180~180,必填;color--描边的颜色,8位16进制表示;fillColor--填充的颜色,8位16进制表示;radius--半径,必填;strokeWidth--描边的宽度。
·controls:控件,包含的属性有,id--控件的id,控件点击事件回调会返回此id;position--控件在地图上的位置,必填,表示位置的属性有left、top、width、height,分别表示控件距地图左上角的距离和控件的宽高;iconPath--显示的图标,相对于根目录路径的图片,必填;clickable--是否可点击,默认不可点击。
·include-points:缩放视野以包括所有给定的坐标点
·show-location:显示带有方向的当前定位点
·bindmarkertap:点击标记点时触发
·bindcontroltap:点击控件时触发
·bindregionchange:视野发生变化时触发
·bindtap:点击地图时触发
示例:
<map id="map" longitude="{{longitude}}" latitude="{{latitude}}" circles="{{circles}}" scale="14" control="{{controls}}" bindcontroltap="controltap" markers="{{markers}}" bindmarkertap ="markertap" polyline="{{polyline}}" bindregionchange="regionchange" show-location style ="width:100%;height:300px;"></map>
Page({data:{latitude:30.5491861989,longitude:104.0680165911,scale:5,
markers:[{iconPath:"./images/flag.png",id:0,latitude:30.5491861989,longitude:104.0680165911,width:30,height:30},
{iconPath:"./images/flag.png",id:1,latitude:30.5468821989,longitude:104.0568565911,width:30,height:30}],
polyline:[{points:[{longitude:104.0680165911,latitude:30.5491961889},
{longitude:104.0687755911,latitude:30.5493481889},
{longitude:104.0688695911,latitude:30.5470661889},
{longitude:104.0685888911,latitude:30.5488321889}],
color:"#0000ffdd",width:2,dottedLine:true}],
controls:[{id:1,iconPath:'./iamges/location.png',
position:{left:0,top:250,width:30,height:30),clickable:true}]},
regionchange(e){console.log(e.type);},
markertap(e){console.log(e.markerId);},
controltap(e){console.log(e.controlId);}});

7)画布组件:

<canvas/>主要用于绘制图形,相当于一块画布,可以在其中绘图。<canvas/>组件是一块无色透明区域,仅仅是图形容器,需要调用相关API来完成实际的绘图任务。
<canvas/>组件默认宽度300px,高度225px,不要在<scroll-view/>中使用<canvas/>。属性有:
·canvas-id:canvas组件的唯一标识符
·disable-scroll:当在canvas中移动时,禁止屏幕滚动以及下拉刷新,默认false
·bindtouchstart:手指触摸动作开始
·bindtouchmove:手指触摸后移动
·bindtouchend:手指触摸动作结束
·bindtouchcancel:手指触摸动作被打断,如来电提醒、弹窗
·bindlongtap:手指长按500ms之后触发,触发了长按事件后进行移动不会触发屏幕滚动
·binderror:当发生错误时触发error事件,detail={errMsg:'soming wrong'}
示例:
<canvas canvas-id="myCanvas" style="width:100%;height:300px;"></canvas>
Page({onReady:function(){var context=wx.createContext();
context.setStrokeStyle("#0000ff");context.setLineWidth(5);
context.rect(3,2,150,200);context.stroke();
wx.drawCanvas({canvasId:'myCanvas',actions:context.getActions()]);
console.log('asdf');}});

8)客服会话:

<contact-button/>用于在页面上显示一个客服会话按钮,用户点击后会进入客服会话。客服会话机制需要后台系统配合,<contact-button/>仅仅作为一个展示组件,目前只能设置大小和图标颜色。属性有:
·size:会话按钮大小,有效值18~27,单位px,默认值18
·type:会话按钮的样式类型,有效值default-dark、default-light,默认值default-dark
·session-from:用户从按钮进入会话时,开发者将收到带上本参数的事件推送,可用于区分用户进入客服会话的来源
示例:
<cantact-button session-from="yoursession" style="margin:100rpx;"></contact-button>

5.API:

小程序的一些功能要依赖框架提供的API来完成,包括网络、媒体、文件、数据缓存、位置、设备、界面、开放接口等8大类,由微信提供,提供逻辑层JS代码进行调用。
微信API有自己的命名规则,其中以wx.on开头的API,如onBackgroundAudioPlay()、wx.onCompassChange()、wx.onSocketOpen等,均代表监听某个事件发生的API接口,这类接口一般来说参数均为一个callback回调函数,当该事件触发时会调用callback函数;不以wx.on开头的API,如wx.request、wx.uploadFile、wx.chooseImage等,通常都接受一个Object对象作为参数,在Object中可以指定success、fail、complete来接收接口调用结果,这三个回调函数有的有返回值,有些没有。示例:
wx.onSocketOpen(function(res){console.log('WebSocket连接已打开');});
wx.request({success:function(){},fail:function(){},complete:function(){}});

1)网络:

每个微信小程序需要事先设置一个通信域名,小程序可以跟指定的域名进行网络通信,包括HTTPS请求wx.request、WebSocket通信wx.connectSocket、上传文件wx.uploadFile、下载文件wx.downloadFile。设置通信域名需要登录小程序“后台-设置-开发设置”,在服务器配置中添加受信任的域。
①发起HTTPS请求:wx.request(Object)
request用于发起HTTPS请求,默认超时时间和最大超时时间为60s。小程序中只能使用HTTPS请求,一个微信小程序只能有5个网络请求连接。Object参数属性有:
·url:后台服务器接口地址,url不能有端口必填项
·data:请求的参数
·header:设置请求的header,header中content-type默认为'application/json',header中不能设置referer,referer格式固定https://servicewechat.com/{appid}/{version}/page-frame.html,其中{appid}为小程序的appid,{version}为小程序的版本号,版本号为0表示为开发版
·method:HTTPS请求方法类型,默认GET,有效值有OPTIONS、GET、HEAD、POST、PUT、DELETE、TRACE、CONNECT,method有效值必须为大写
·dataType:默认为json。如果设置了dataType为json,则会尝试对响应的数据做JSON.parse
·success:收到服务器成功返回的回调函数,res={data:'开发者服务器返回的内容'}
·fail:接口调用失败的回调函数
·complete:接口调用结束的回调函数,调用成功、失败都会执行
data数据最终发送给服务器的数据是String类型,如果传入的data不是String类型,则会被转化成String。转化规则:
对于header['content-type']为'application/json'的数据,会对数据进行JSON序列化
对于header['content-type']为'application/x-www-form-urlencoded'的数据,会将数据转换成query string(encodeURIComponent(k)=encodeURIComponent(v)&encodeURIComponent(k)
=encodeURIComponent(v)...)
示例:
wx.request({url:'https://www.dmall.com',header:{'Content-Type':'application/json'},
success:function(e){console.log(e);},
complete:function(){console.log('无论成功失败都会执行');}});
②上传:wx.uploadFile(Object)
如果需要提交带有本地资源的数据,需要调用此接口将本地资源上传到指定服务器。调用这个uploadFile时,客户端会向服务器端发起一个HTTP POST请求,header中Content-Type为multipart/form-data。上传文件最大并发限制为10个,默认超时时间和最大超时时间都是60s。Object参数属性有:
·url:开发者服务器url,必填
·filePath:要上传文件资源的路径,必填
·name:文件对应的key,开发者在服务器端通过这个key可以获取到文件的二进制内容,必填
·header:设置请求的header,header中不能设置referer,referer格式固定https://servicewechat.com/{appid}/{version}/page-frame.html,其中{appid}为小程序的appid,{version}为小程序的版本号,版本号为0表示为开发版
·formData:HTTP请求中其他额外的请求数据
·success:收到服务器成功返回的回调函数,success返回参数属性为data--开发者服务器返回的数据;statusCode--HTTP状态码
·fail:接口调用失败的回调函数
·complete:接口调用结束的回调函数,调用成功、失败都会执行
示例:
wx.chooseImage({success:function(res){var tempFilePaths=res.tempFilePaths;
wx.uploadFile({url:'http://www.myserver.com',filePath:tempFilePaths[0],name:'myFile',
formData:{'otherData':'value'},
success:function(response){var data=response.data;}});}});
③下载:wx.downloadFile(Object)
从服务器端下载资源到本地。调用API后,客户端直接发起一个HTTP GET请求,把文件下载到本地并返回文件的本地临时路径,临时文件在小程序本次启动期间可以正常使用,如需持久保存,需要主动调用wx.saveFile进行保存。下载文件最大并非限制为10个,默认超时时间和最大超时时间都是60s。Object参数属性有:
·url:下载资源的URL,必填
·header:设置请求的header,header中不能设置referer,referer格式固定https://servicewechat.com/{appid}/{version}/page-frame.html,其中{appid}为小程序的appid,{version}为小程序的版本号,版本号为0表示为开发版
·success:收到服务器成功返回的回调函数,res={tempFilePath:'文件临时路径'},文件临时路径在小程序启动期间可以正常使用,如需持久保存,需要主动调用wx.saveFile方法,这样才能保证小程序下次启动时也能访问
·fail:接口调用失败的回调函数
·complete:接口调用结束的回调函数,调用成功、失败都会执行
示例:
wx.downloadFile({url:'http://www.myserver.com',
success:function(res){wx.getImageInfo({src:res.tempFilePaths[0],
success:function(info){console.log(info.width+','+info.height);}});}});
④WebSocket:
在需要即时通信时,可以利用小程序提供的WebSocket相关API创建,实现长连接。
⑴wx.connectSocket(Object):
创建一个WebSocket连接。一个小程序同时只能有一个WebSocket连接,创建新连接时,如果当前已存在一个WebSocket连接,会自动关闭该连接,并重新创建一个新连接,创建连接时默认和最大超时时间都是60s。Object参数有:
·url:服务器接口地址,必须是WSS协议,且域名必须是后台配置的合法域名,必填
·data:请求的数据
·header:设置请求的header,header中content-type默认为'application/json',header中不能设置referer,referer格式固定https://servicewechat.com/{appid}/{version}/page-frame.html,其中{appid}为小程序的appid,{version}为小程序的版本号,版本号为0表示为开发版
·method:请求方式,默认GET,有效值有OPTIONS、GET、HEAD、POST、PUT、DELETE、TRACE、CONNECT,非必填
·success:接口调用成功的回调函数
·fail:接口调用失败的回调函数
·complete:接口调用结束的回调函数,调用成功、失败都会执行
示例:
wx.connectSocket({url:'wss://www.myserver.com',
data:{myData:'data'},
header:{'Content-Type':'application/json'},method:'get'});
⑵wx.onSocketOpen(callback):
监听WebSocket连接打开事件。示例:
wx.connectSocket({url:'wss://www.myserver.com',]);
wx.onSockerOpen(function(res){console.log('socket连接已打开');});
⑶wx.onSocketError(callback):
监听WebSocket错误。示例:
wx.onSocketError(function(res){console.log('连接打开失败');});
⑷wx.sendSocketMessage(callback):
通过WebSocket连接发送数据,需要先通过wx.connectSocket连接后台,并在wx.onSocketOpen回调之后才能发送内容。Object参数属性有:
·data:需要发送的内容,必填
·success:接口调用成功的回调函数
·fail:接口调用失败的回调函数
·complete:接口调用结束的回调函数,无论调用成功或失败都会执行
示例:
var socketOpen=false;
var socketMsgQueue=[];
wx.connectSocket({url:'wss://www.myserver.com',]);
wx.onSockerOpen(function(res){socketOpen=true;
for(var i=0,msg;msg=socketMsgQueue[i];++i){sendMsg(msg);}
socketMsgQueue=[];});
function sendMsg(msg){if(!socketOpen){socketMsgQueue.push(msg);return;}
wx.sendSocketMessage({data:msg});}
sendMsg({myName:'weixin'});
⑸wx.onSocketMessage(callback):
监听WebSocket接收到服务器的消息事件。callback返回参数为data,是服务器返回的消息。
wx.onSocketMessage(function(res){console.log('收到服务器内容:'+res.data);});
⑹wx.closeSocket():
关闭WebSocket连接。示例:
wx.closeSocket();
⑺wx.onSocketClose(callback):
监听WebSocket是否关闭,当WebSocket成功关闭时触发。示例:
wx.onSocketClose(function(){console.log('连接关闭');});

2)媒体:

①图片:
⑴wx.chooseImage(Object):
从本地相册选择图片或者使用相机拍照。拍照时产生的临时路径,在小程序本次启动期间可以正常使用,如需持久保存,需要主动调用wx.saveFile,这样才能保证小程序下次启动时能访问到。Object参数属性有:
·count:最多可以选择的图片张数,默认9
·sizeType:图片尺寸类型,有效值为original原图、compressed压缩图,默认二者都有
·sourceType:获取图片的方式,有效值album从相册选图、camera用相机,默认二者都有
·success:成功则返回图片的本地文件路径列表tempFilePaths,必填
·fail:接口调用失败的回调函数
·complete:接口调用结束的回调函数,无论调用成功或失败都会执行
示例:
<view><image src="{{src}}"></image>
<button bindtap="chooseImage">选择图片</button></view>
Page({src:'',
chooseImage:function(){var self=this;
wx.chooseImage({count:1,sizeType:['original','compressed'],
sourceType:['album','camera'],success:function(res){console.log(res.tempFilePaths);}});}});
⑵wx.previewImage(Object):
预览图片,调用后小程序会开启图片浏览界面。Object参数属性有:
·current:当前显示图片的链接,链接地址必须是urls中已存在的链接,不填则默认为urls的第一张
·urls:需要预览的图片链接列表,必填
·success:接口调用成功的回调函数
·fail:接口调用失败的回调函数
·complete:接口调用结束的回调函数,无论调用成功或失败都会执行
示例:
wx.previewImage({current:'http://www.uimaker.com/uploads/allimg/130301/123.jpg',
urls:['http://www.uimaker.com/uploads/allimg/130301/456.jpg',
'http://www.uimaker.com/uploads/allimg/130301/789.jpg']});
⑶wx.getImageInfo(Object):
获取图片信息。Object属性有:
·src:图片的路径,可以是相对路径、临时文件路径、存储文件路径、网络图片路径
·success:接口调用成功的回调函数,返回参数中Width为图片宽度height为图片高度,单位均为px
·fail:接口调用失败的回调函数
·complete:接口调用结束的回调函数,无论调用成功或失败都会执行
示例:
chooseImage:function(){wx.chooseImage({success:function(res){
wx.getImageInfo({src:res.tempFilePaths[0],success:function(info){console.log(info);}});}});
②录音:
⑴wx.startRecord(Object):
开始录音。当主动调用wx.stopRecord,或录音时间超过1分钟时自动结束录音,返回录音文件的临时路径。当用户离开小程序后,此接口无法调用。录音接口需要用户授权,业务代码中需要考虑。Object参数属性:
·success:录音成功后调用,返回录音文件的临时文件目录,res={tempFilePath:'录音文件的临时路径'}
·fail:接口调用失败的回调函数
·complete:接口调用结束的回调函数,无论调用成功或失败都会执行
示例:
wx.startRecord({success:function(res){var tempFilePath=res.tempFilePath;
wx.playVoice({filePath:tempFilePath})}}); //录音完成后立即播放
⑵wx.stopRecord():
主动调用停止录音。示例:
setTimeout(function(){wx.stopRecord();},10000);
③音频播放控制:
⑴wx.playVoice(Object):
开始播放录音,同时只允许一个语音文件播放,如果前一个语音文件还没有播完,将中断前一个语音播放。Object参数属性有:
·filePath:需要播放的语音文件路径,必填
·success:调用接口成功的回调函数
·fail:接口调用失败的回调函数
·complete:接口调用结束的回调函数,无论调用成功或失败都会执行
⑵wx.pauseVoice():
暂停正在播放的语音。再次调用wx.playVoice播放同一个文件时,会从暂停处开始播放。如果想从头开始播放,需要先调用wx.stopVoice。
⑶wx.stopVoice():
结束播放录音。
④音乐播放控制:
⑴wx.getBackgroundAudioPlayerState(Object):
获取后台音乐播放状态。调用本方法时可以获取<audio/>组件或wx.playBackgroundAudio()方法播放的音乐。Object参数属性有:
·success:调用接口成功的回调函数,success返回参数属性包括duration--选定音频的长度,单位s,只有在当前有音乐播放时返回;currentPosition--选定音频的播放位置,单位s,只有在当前有音乐播放时返回;status--播放状态,0为暂停中,1为播放中,2为没有音乐在播放;downloadPercent--音频的下载速度,为整数,如80代表80%,只有在当前有音乐播放时返回;dataUrl--歌曲数据链接,只有在当前有音乐播放时返回。
·fail:接口调用失败的回调函数
·complete:接口调用结束的回调函数,无论调用成功或失败都会执行
示例:
wx.getBackgroundAudioPlayerState({success:function(res)
{var statusText={2:'无音乐在播放',1:'播放中',0:'暂停中'};console.log(statueText[res.status]);}});
⑵wx.playBackgroundAudio(Object):
播放音乐,同时只能有一首音乐在播放。Object参数属性有:
·dataUrl:音乐链接,必填
·title:音乐标题
·coverImgUrl:封面URL
·success:调用接口成功的回调函数
·fail:接口调用失败的回调函数
·complete:接口调用结束的回调函数,无论调用成功或失败都会执行
示例:
wx.playBackgroundAudio({dataUrl:'./music/mymusic.mp3',title:'我的音乐',
coverImgUrl:'./images/poster.jpg',success:function(){console.log('开始播放音乐了');}});
⑶wx.pauseBackgroundAudio():
暂停播放音乐。示例:
setTimeout(function(){console.log('暂停播放');wx.pauseBackgroundAudio();},60000);
⑷wx.seekBackgroundAudio(Object):
控制音乐播放进度,可以实现快进、快退和播放位置拖动功能。Object属性有:
·position:音乐位置,单位秒
·success:调用接口成功的回调函数
·fail:接口调用失败的回调函数
·complete:接口调用结束的回调函数,无论调用成功或失败都会执行
示例:
wx.getBackgroundAudioPlayerStatue({
success:function(res){var currentPosition=res.currentPosition;
wx.seekBackgroundAudio({position:currentPosition+30});}});
⑸wx.stopBackgroundAudio():
停止播放音乐。示例:
setTimeout(function(){console.log('停止播放');wx.stopBackgroundAudio();},60000);
⑹wx.onBackgroundAudioPlay(callback):
监听音乐播放。示例:
wx.onBackgroundAudioPlay(function(){console.log('音乐播放');});
⑺wx.onBackgroundAudioPause(callback):
监听音乐暂停。示例:
wx.onBackgroundAudioPause(function(){console.log('音乐暂停');});
⑻wx.onBackgroundAudioStop(callback):
监听音乐停止。示例:
⑤音频组件控制:
wx.createAudioContext(audioId)创建并返回audio上下文audioContext对象。audioContext对象通过audioId和一个<audio/>组件绑定,通过它可以操作对应的<audio/>组件。audioContext对象的方法有:
·setSrc:设置音频地址
·play:播放
·pause:暂停
·seek:跳转到指定位置,单位为s
利用播放相关API配合<audio/>可以创建自定义样式播放器。示例:
<view class="custom-audio">
<audio id="myAudio" style="display:none;"></audio>
<image class="poster" mode="widthFix" src="http://www.yoka.com/dna/pics/d1234.jpg">
</image>
<view class="actions" bindtap="action">
<view data-type="play">播放</view>
<view data-type="pause">暂停</view>
<view data-type="seek">跳到30秒</view>
<view data-type="reset">回到开头</view>
</view>
</view>
.custom-audio{width:500rpx;border:solid 1px #ccc;border-bottom:0;margin:60rpx auto;}
.custom-audio .poster{width:80%;border-radius:50%;margin:10%;}
.cunstom-audio .actions view{height:80rpx;line-height:80rpx;text-align:center;border:solid 1px #ccc;border-width:1px 0px;background:-webkit-gradient(linear,0% 0%,0% 100%,from(#fff), to(#eee)); margin-top:10rpx;}
Page({onReady:function(e){
this.audioContext=wx.createAudioContext('myAudio');
this.audioContext.setSrc('http://ws.stream.qqmusic.qq.com/edgg.mps?guid=dddd&uin=ssssdee&vkey=dffrffgf7&fromtag=46');},
action:function(e){var type=e.target.dataset.type,audioContext=this.audioContext;
switch(type){case 'play':audioContext.play();break;
case 'pause':audioContext.pause();break;case 'seek':audioContext.seek(30);break;
case 'reset': audioContext.seek(0);break;}}});
⑥视频:
wx.chooseVideo(Object)拍摄视频或从手机相册中选取视频,返回视频的临时文件路径。Object参数属性有:
·sourceType:获取视频方式,album从相册选中视频,camer使用相机拍摄,默认值为['album','camera']。
·maxDuration:拍摄视频最长拍摄时间,单位秒,最长支持60秒
·camera:拍摄适配的方式用前置或后置摄像头,默认为前后都有['album','camera']
·success:调用接口成功的回调函数,返回视频文件的临时文件路径,返回参数属性包括tempFilePath--选定视频的临时文件路径;duration--选定视频的时间长度;size--选定视频的数据量大小;height--选定视频的高;width--选定视频的宽
·fail:接口调用失败的回调函数
·complete:接口调用结束的回调函数,无论调用成功或失败都会执行
示例:
wx.chooseVideo({sourceType:['album','camera'],camera:['front','back'],
success:function(res){console.log(res.tempFilePath);}});
⑦视频组件控制:
wx.createVideoContext(videoId)用于创建并返回video上下文videoContext对象。videoContext对象的方法有:
·play:播放
·pause:暂停
·seek:跳转到指定位置,单位秒
·sendDanmu:发送弹幕,danmu包含text、color两个属性
示例:
<video src="./video/myvideo.mp4" id="myVideo"></video>
<button bindtap="play">播放</button>
<button bindtap="pause">暂停</button>
<button bindtap="restart">回到开头</button>
<button bindtap="sendDanmu">发送弹幕</button>
Page({onReady:function(){this.videoContext=wx.createVideoContext('myVideo');},
play:function(){this.videoContext.play();},
pause:function(){this.videoContext.pause();},
restart:function(){this.videoContext.seek(0);},
sendDanmu:function(){this.videoContext.sendDanmu({text:'弹幕文案',color:'#ff0000'});}});

3)文件:

从网络下载、拍照、录音、录视频时,文件都是存在临时文件中,需要永久保存这些文件就需要主动调用API进行保存,这时小程序会将文件保存到系统指定目录。这些文件操作都需要调用相关API。
⑴wx.saveFile(Object):
保存文件到本地,本地文件存储大小限制为10MB。Object参数属性有:
·tempFilePath:需要保存文件的临时路径,必填
·success:返回文件的保存路径,res={savedFilePath:'文件的保存路径'}
·fail:接口调用失败的回调函数
·complete:接口调用结束的回调函数,无论调用成功或失败都会执行
示例:
wx.startRecord({success:function(res){var tempFilePath=res.tempFilePath;
wx.saveFile({tempFilePath:tempFilePath,
success:function(res){var savedFilePath=res.savedFilePath;
console.log('录音文件已保存到'+savedFilePath);}})}});
⑵wx.getSavedFileList(Object):
获取本地保存文件列表,Object参数属性有:
·success:接口调用成功的回调函数,返回参数属性包括errMsg--接口调用结果;fileList--文件列表,fileList的属性包括filepath文件的本地路径、createTime文件保存的时间戳,size文件的大小,createTime为timestamp,文件大小单位为B。
·fail:接口调用失败的回调函数
·complete:接口调用结束的回调函数,无论调用成功或失败都会执行
示例:
wx.getSavedFileList({success:function(res){
for(var i=0,file;file=res.fileList[i];++i){
console.log('第'+i+'个文件路径:'+file.filePath);}}});
⑶wx.getSavedFileInfo(Object):
获取文件的文件信息。Object属性有:
·filePath:文件路径,必填
·success:接口调用成功的回调函数,success返回参数属性包括errMsg--接口调用结果;size--文件大小,单位B;createTime--文件保存的时间戳。
·fail:接口调用失败的回调函数
·complete:接口调用结束的回调函数,无论调用成功或失败都会执行
示例:
wx.getSavedFileList({
success:function(){
for(var i=0,file;file=res.fileList[i];++i){
wx.getSavedFileInfo({filePath:file.filePath,
success:function(res){console.log('文件大小为:'+res.size);}});}}});
⑷wx.removeSavedFile(Object):
删除本地存储的文件。Object参数属性有:
·filePath:需要删除的文件路径,必填
·success:接口调用成功的回调函数
·fail:接口调用失败的回调函数
·complete:接口调用结束的回调函数,无论调用成功或失败都会执行
示例:
wx.getSavedFileList({success:function(res){
for(var i=0,file;file=res.fileList[i];++i){
wx.removeSavedFile({filePath:file.filePath});}}});
⑸wx.openDocument(Object):
在新页面中打开文档,支持格式doc、docx、xls、xlsx、ppt、pptx、pdf。Object参数属性有:
·filePath:文件路径,可通过wx.downFile获得,必填
·success:接口调用成功的回调函数
·fail:接口调用失败的回调函数
·complete:接口调用结束的回调函数,无论调用成功或失败都会执行
示例:
wx.downloadFile({url:'http://www.myserver.com/my.docx',
success:function(res){var filePath=res.filePath;wx.openDocument({filePath:filePath});}});

4)数据缓存:

每个小程序都可以有自己的本地缓存,local Storage是永久存储的,本地缓存最大为10MB,根据数据操作API分为同步和异步两种。
①保存数据:
⑴wx.setStorage(Object):
将数据存在本地缓存指定的key中,会覆盖掉原来key对应的内容,这是一个异步接口。Object参数属性有:
·key:本地缓存中指定的key,必填
·data:需要存储的内容,必选,必填
·success:接口调用成功的回调函数
·fail:接口调用失败的回调函数
·complete:接口调用结束的回调函数,无论调用成功或失败都会执行
示例:
wx.setStorage({key:'myKey',value:'myValue'});
⑵wx.setStorageSync(KEY,DATA):
将数据存在本地缓存指定的key中,会覆盖掉原来该key对应的内容,这是一个同步接口。参数说明:
·key:本地缓存中指定的key
·data:需要存储的内容
示例:
wx.setStorageSync('myKey','myValue');
②获取数据:
⑴wx.getStorage(object):
从本地缓存中异步获取指定key对应的内容。Object参数属性有:
·key:本地缓存中指定的key,必填
·success:接口调用成功的回调函数,res={data:key对应的内容},必填
·fail:接口调用失败的回调函数
·complete:接口调用结束的回调函数,无论调用成功或失败都会执行
示例:
wx.getStorage({key:'myKey',success:function(res){console.log(res.data);}});
⑵wx.getStorageSync(KEY):
从本地缓存中同步获取指定key的对应内容。参数key为本地缓存中的指定key,必填
示例:
var value=wx.getStorageSync('myKey');
console.log(value);
③获取本地数据信息:
⑴wx.getStorageinfo(Object):
异步获取当前storage的相关信息。Object参数属性有:
·success:接口调用的回调函数,返回参数包含的属性有keys--当前storage中所有的key;currentSize--当前占用的空间大小,单位kb;limitSize--限制的空间大小,单位kb。
·fail:接口调用失败的回调函数
·complete:接口调用结束的回调函数,无论调用成功或失败都会执行
示例:
wx.getStorageInfo({success:function(res){var p;
for(p in res.keys){console.log(p+':'+wx.getStorageSync(p));}}});
⑵wx.getStorageInfoSync():
同步获取当前storage的相关信息。示例:
var p,info=wx.getStorageInfoSync();
for(p in info.keys){console.log(p+':'+wx.getStorageSync(p));}
④删除数据:
⑴wx.removeStorage(Object):
根据key值异步删除本地数据。Object参数属性有:
·key:本地缓存中指定的key,必填
·success:接口调用的回调函数,必填
·fail:接口调用失败的回调函数
·complete:接口调用结束的回调函数,无论调用成功或失败都会执行
示例:
wx.removeStorage({key:'myKey',success:function(res){console.log(res.data};}});
⑵wx.removeStorageSync(Key):
根据key值同步删除本地数据。示例:
wx.removeStorageSync('myKey');
⑤清空数据:
⑴wx.clearStorage():
清理本地数据缓存。示例:
wx.clearStorage();
⑵wx.clearStorageSync():
wx.clearStorageSync();

5)位置:

①获取位置:
坐标体系有多种,小程序支持WGS84和GCj02。WGS84是国际上通用的坐标系,GCj02为火星坐标系,是由中国国家测绘局制定的地理信息系统的坐标系统,是由WGS84坐标系经加密后的坐标系。小程序中查看位置使用的是GCj02坐标。
wx.getLocation(Object)用于获取当前的地理位置、速度,需要开启定位功能,当用户离开小程序后,此接口无法调用;当用户点击“显示在聊天顶部”时,此接口可继续调用。Object参数属性有:
·type:默认为wgs返回gps坐标,gcj02返回可用于wx.openLocation的坐标
·success:接口调用成功的回调函数,必填,返回参数属性包括latitude--纬度,浮点值,范围-90~90,负数表示南纬;longitude--经度,浮点数,范围-180~180,负数表示西经;speed--速度,浮点数,单位m/s;accuracy--位置的精确度。
·fail:接口调用失败的回调函数
·complete:接口调用结束的回调函数,无论调用成功或失败都会执行
示例:
wx.getLocation({type:'wgs84',success:function(res){console.log(res);}});
②选择位置:
wx.chooseLocation(Object)用于打开地图选择位置,用于选中后返回选中信息。Object参数属性有:
·success:接口调用成功的回调函数,必填。success返回参数属性包括name--位置名称;address--详细地址;latitude--纬度,浮点数,范围-90~90,负数表示南纬;longitude--经度,浮点数,范围-180~180,负数表示西经。
·fail:接口调用失败的回调函数
·complete:接口调用结束的回调函数,无论调用成功或失败都会执行
示例:
wx.chooseLocation({success:function(res){console.log(res.address);}});
③查看位置:
wx.openLocation(Object)用于在微信内置地图查看位置。Object参数属性有:
·latitude:纬度,浮点数,范围-90~90,负数表示南纬
·longitude:longitude--经度,浮点数,范围-180~180,负数表示西经
·scale:缩放比例,范围1~28,默认28
·name:位置名
·address:地址的详细说明
·success:接口调用的回调函数,必填
·fail:接口调用失败的回调函数
·complete:接口调用结束的回调函数,无论调用成功或失败都会执行
示例:
wx.getLocation({type:'gcj02',
success:function(res){wx.open({latitude:res.latitude,longitude:res.longitude});}});
④地图组件控制:
wx.createMapContext(Object)用于创建并返回map上下文mapContext对象,mapContext通过mapId跟一个<map/>组件绑定,通过它可以操作对应的<map/>组件。mapContext对象的方法有:
·getCenterLocation:获取当前地图中心的经纬度,返回的是gcj02坐标,可用于wx.openLocation。getCenterLocation参数属性包括success--接口调用成功的回调函数,res= {longitude:'经度',latitude:'纬度'};fail--接口调用失败的回调函数;complete--接口调用结束的回调函数,无论调用成功或失败都会执行。
·moveToLocation:将地图中心移动到当前定位点,需要配合map组件的showlocation使用。
示例:
<map id="myMap" show-location/>
<button data-type="getCenterLocation" bindtap="action">获取位置</button>
<button data-type="location" bindtap="action">移动位置</button>
onReady:function(e){this.mapContext=wx.createMapContext('myMap');),
action:function(e){var type=e.target.dataset.type,mapContext=this.mapContext;
switch(type){case 'getCenterLocation':mapContext.getCenterLocation({
success:function(res){console.log(res.longitude+','+res.latitude);}});
case 'location':mapContext.moveToLocation();}}});

6)设备:

①系统信息:
⑴wx.getSystemInfo(Object):
异步获取系统信息。Object参数属性有:
·success:接口调用成功回调函数,返回系统相关信息,必填,返回参数属性包括model--手机型号;pixelRatio--设备像素比;windowWidth--窗口宽度;windowHeight--窗口高度;language--微信设置的语言;version--微信版本号;system--操作系统版本;platform--客户端平台。
·fail:接口调用失败的回调函数
·complete:接口调用结束的回调函数,无论调用成功或失败都会执行
示例:
wx.setSystemInfo({success:function(info){console.log(info);}});
⑵wx.getSystemInfoSync():
同步获取系统信息。示例:
var info=wx.getSystemInfoSync();
console.log(info);
②网络状态:
wx.getNetworkType(Object)用于获取网络类型。Object参数属性有:
·success:接口调用成功回调函数,返回网络类型networkType,必填
·fail:接口调用失败的回调函数
·complete:接口调用结束的回调函数,无论调用成功或失败都会执行
示例:
wx.getNetworkType({success:function(res){console.log(res.networkType);}}});
③重力感应:
wx.onAccelerometerChange(callback)用于监听重力感应数据,频率5次/秒。callback返回参数属性有:
·x:X轴重力感应,值为当前轴上重力加速度/重力加速度(9.8)
·y:Y轴重力感应,值参考x轴
·z:Z轴重力感应,值参考x轴
示例:
<view>{{x}},{{y}},{{z}}</view>
Page({data:{x:0,y:0,z:0},
onReady:function(){var self=this;wx.onAcceleromerChange(function(res){
self.setData({x:res.x,y:res.y,z:res.z});})}});
④罗盘:
wx.onCompassChange(callback)用于监听罗盘数据,频率5次/秒,调用罗盘需要开启定位功能。callback参数的属性有direction,为当前向的方向度数,正北方为0,范围为0~360,-1表示没有开启定位功能。示例:
wx.onCompressChange(function(res){console.log(res.direction);});
⑤拨打电话:
wx.makePhoneCall(Object)用于调用手机拨打电话功能。Object参数的属性有:
·phoneNumber:需要调用成功回调函数
·success:接口调用成功回调函数
·fail:接口调用失败的回调函数
·complete:接口调用结束的回调函数,无论调用成功或失败都会执行
示例:
wx.makePhoneCall({phoneNumber:'13456789100'});
⑥扫码:
scanCode(Object)调用客户端扫码界面,扫码成功后返回对应结果。Object参数有:
·success:接口调用成功的回调函数,返回参数包括result--扫码的内容;scanType--所扫码的类型;charSet--所扫码的字符集;path--当扫的码为当前小程序的合法二维码时,会返回此字段,内容为二维码携带的path。
·fail:接口调用失败的回调函数
·complete:接口调用结束的回调函数,无论调用成功或失败都会执行
示例:
wx.scanCode({success:function(res){console.log(res.result);}});

7)界面:

①交互反馈:
⑴wx.showToast(Object):
显示消息提示框。Object参数的属性有:
·title:提示内容,必填
·icon:图标,只支持success、loading
·duration:提示的延迟时间,到了指定时间自动关闭,单位毫秒,默认1500,最大10000
·mask:是否显示透明蒙层,防止触摸穿透,默认false
·success:接口调用成功的回调函数
·fail:接口调用失败的回调函数
·complete:接口调用结束的回调函数,无论调用成功或失败都会执行
示例:
wx.showToast({title:'操作成功',icon:'success'});
⑵wx.hideToast():
隐藏消息提示框。示例:
wx.showToast({title:'请稍等...',icon:'loading',duration:10000});
setTimeout(function(){wx.hideToast();},2000);
⑶wx.showModal(Object):
显示模态弹窗。Object参数的属性有:
·title:提示的标题,必填
·content:提示的内容,必填
·showCancel:是否显示取消按钮,默认true
·cancelText:取消按钮的文字,默认为“取消”,最多4个字符
·cancelColor:取消按钮的文字颜色,默认#000000
·confirmText:确定按钮的文字,默认“确定”,最多4个字符
·confirmColor:确定按钮的文字颜色,默认#3cc51f
·success:接口调用成功的回调函数,返回结果res.confirm为true时,表示用户点击确定按钮
·fail:接口调用失败的回调函数
·complete:接口调用结束的回调函数,无论调用成功或失败都会执行
有些版本的wx.showModel返回的confirm一直为true。示例:
wx.showModel({title:'标题',content:'内容',
success:function(res){if(!res.confirm){return;}console.log('用户点击了确定');}});
⑷wx.showActionSheet(Object):
显示操作菜单。Object参数的属性有:
·itemList:按钮的文字数组,数组长度最大为6个,必填
·itemColor:按钮的文字颜色,默认#000000
·success:接口调用成功回调函数,返回参数包括cancel--用户是否取消选择;tapIndex--用户点击的按钮,从上到下的顺序,从0开始
·fail:接口调用失败的回调函数
·complete:接口调用结束的回调函数,无论调用成功或失败都会执行
②设置导航条:
⑴wx.setNavigationBarTitle(Object):
动态设置当前页面的标题。Object参数属性有:
·title:页面标题,必填
·success:接口调用成功回调函数
·fail:接口调用失败的回调函数
·complete:接口调用结束的回调函数,无论调用成功或失败都会执行
示例:
wx.setNavigationBarTitle({title:'新页面'});
⑵wx.showNavigationBarLoading():
在当前页面显示导航条加载动画。示例:
Page({onShow:function(){wx.showNavigationBarLoading();}});
⑶wx.hideNavigationBarLoading():
隐藏导航条加载动画。示例:
Page({onLaunch:function(){wx.hideNavigationBarLoading();}});
③导航:
⑴wx.navigateTo(Object):
保留当前页面,跳转到应用内的某个页面,使用wx.navigateBack可以返回到原页面,小程序中页面路径最多5层。Object参数的属性有:
·url:需要跳转的应用内页面的路径,路径后可带参数,必填。参数与路径之间使用?分隔,参数键与参数值用=相连,不同参数用&分隔,如'path?key=value&key2=value2'
·success:接口调用成功回调函数
·fail:接口调用失败的回调函数
·complete:接口调用结束的回调函数,无论调用成功或失败都会执行
示例:
wx.navigateTo({url:'../newpage?key1=value1'});
Page({onLoad:function(option){console.log(option.query);}});
⑵wx.redirectTo(Object):
关闭当前页面,跳转到应用内的某个页面。Object参数属性有:
·url:需要跳转的应用内页面的路径,路径后可带参数,必填。参数与路径之间使用?分隔,参数键与参数值用=相连,不同参数用&分隔,如'path?key=value&key2=value2'
·success:接口调用成功回调函数
·fail:接口调用失败的回调函数
·complete:接口调用结束的回调函数,无论调用成功或失败都会执行
示例:
wx.redirectTo({url:'../newpage?key1=value1'});
⑶wx.switchTab(Object):
跳转到tabBar页面,并关闭其他所有非tabBar页面。Object参数的属性有:
·url:需要跳转的tabBar页面的路径,需在app.json的tabBar字段定义的页面,路径后不能带参数,必填
·success:接口调用成功回调函数
·fail:接口调用失败的回调函数
·complete:接口调用结束的回调函数,无论调用成功或失败都会执行
示例:
wx.switchTab({url:'/home'});
app.json的配置:
{"tabBar":{"list":[{"pagePath":"home","text":'首页'},
"pagePath":"other","text":'其他页面'}]}}
⑷wx.navigateBack(Object):
关闭当前页面,返回上一页面或多级页面。可通过getCurrentPages()获取当前的页面栈,以决定返回几层。Object参数的属性为delta,是返回的页面数,如果delta大于现有的页面数,则返回首页,默认值为1。示例:
wx.navigateBack({delta:3});
④下拉刷新:
⑴onPullDownRefresh(callback):
监听下拉刷新事件。需要在Page中定义onPullDownRefresh处理函数,还需要在app.json配置中开启window配置的enablePullDownRefresh选项。当处理完数据刷新后,可以调用wx.stopPullDownRefresh方法停止当前页面的下拉刷新。
⑵wx.stopPullDownRefresh():停止当前页面下拉刷新。
示例:
Page({onPullDownRefresh:function(){wx.stopPullDownRefresh();}});

8)动画:

wx.createAnimation(Object)用于创建一个动画实例animation。可以调用动画实例的方法来描述动画,最后通过动画实例的export方法导出动画数据,传递给组件animation属性,每次调用exports方法会清掉之前的动画操作。Object参数的属性有:
·duration:动画持续时间,单位ms,默认值400
·timingFunction:定义动画的效果,有效值有linear、ease、ease-in、ease-in-out、ease-out、step-start、step-end,默认值linear
·delay:动画延迟时间,单位ms,默认0
·transformOrigin:设置transform-origin,默认“50% 50% 0”
示例:
var animation=wx.createAnimation({transformOrigin:'0 0',
duration:20000,timingFunction:'ease-in'});
①动画描述:
创建实例后,需要调用实例动画方法来描述动画。这些方法调用后会返回自身,支持链式调用的方法,动画描述方法按类型可分为样式、旋转、缩放、偏移、倾斜、矩阵变换。
⑴样式:
·opacity(value):设置透明度,参数value为透明度,范围0~1
·backgroundColor(color):设置背景色,参数color为颜色值
·width(length):设置宽度
·height(length):设置高度
·top(length):设置top属性
·left(length):设置left属性
·bottom(length):设置bottom属性
·right(length):设置right属性
属性值length为长度值,传入Number默认使用px,可传入其他自定义单位的长度
⑵旋转:
·rotate(deg):从原点顺时针旋转一个deg角度,参数deg范围-180~180
·rotateX(deg):在X轴旋转一个deg角度,参数deg范围-180~180
·rotateY(deg):在Y轴旋转一个deg角度,参数deg范围-180~180
·rotateZ(deg):在Z轴旋转一个deg角度,参数deg范围-180~180
·rotate3d(x,y,z,deg):旋转的简写方法,参数x、y、z分别是在x、y、z轴旋转的角度,范围-180~180;deg为从原点顺时针旋转的角度,参数deg范围-180~180
⑶缩放:
·scale(sx,sy):同时设置在X轴、Y轴的缩放。参数sx、sy分别表示在X、Y轴缩放的倍数,如果只有一个参数表示X和Y轴缩放同样的倍数。
·scaleX(sx):设置X轴缩放,参数sx为X轴缩放的倍数
·scaleY(sy):设置Y轴缩放,参数sy为Y轴缩放的倍数
·scaleZ(sz):设置Z轴缩放,参数sz为Z轴缩放的倍数
·scale3d(sx,sy,sz):同时控制X、Y、Z轴缩放,参数分别为X、Y、Z轴缩放的倍数
⑷偏移:
·translate(tx,ty):表示在X、Y轴的偏移量,参数tx、ty分别表示在X、Y轴的偏移,如果只有一个参数表示X轴偏移,单位px。
·translateX(tx):表示在X轴的偏移量,参数tx表示在X轴的偏移,单位px。
·translateY(ty):表示在Y轴的偏移量,参数ty表示在Y轴的偏移,单位px。
·translateZ(tz):表示在Z轴的偏移量,参数tz表示在Z轴的偏移,单位px。
·translate3d(tx,ty,tz):表示在X、Y、Z轴的偏移量,参数tx、ty、tz分别表示在X、Y、Z轴的偏移,单位px。
⑸倾斜:
·skew(ax,ay):表示在X、Y轴倾斜,参数ax、ay分别表示在X、Y轴的倾斜度,如果只有一个参数表示X轴的倾斜度。
·skewX(ax):表示在X轴倾斜,参数ax表示在X轴的倾斜度
·skewY(ay):表示在Y轴倾斜,参数ay表示在Y轴的倾斜度
⑹矩阵变换:
·matrix(a,b,c,d,tx,ty):定义矩阵变换,基于X轴和Y轴坐标重新定位元素位置,与CSS3的transform-function matrix
`matrix3d():定义矩阵变换,基于X、Y、Z轴重新定位元素位置,同CSS3中transform-function matrix3d
②动画队列:
调用动画操作方法后要调用step()来表示一组动画完成,可以在一组动画中调用任意多个动画方法,一组动画中的所有动画会同时开始,一组动画完成后才会进行下一组动画。step可以传入一个跟wx.createAnimation()一样的配置参数,用于指定当前组动画的配置。在某些版本,通过step()分隔动画时,只有第一步动画能生效。示例:
<view style="width:100%;height:200px;">
<icon animation="{{animData}}" style="position:absolute;left:100px;" type="success"
size="40"/>
</view>
<button bindtap="rotateAndMove">旋转并移动</button>
<button bindtap="rotateThenMove">旋转后移动</button>
Page({data:{animData:{}},
rotateAndMove:function(){var anim=wx.createAnimation({
duration:1000,timingFunction"'ease'});
anim.translateY('100px').rotate('720').step();
this.setData({animData:anim.export()}):},
rotateThenMove:function(){var anim=wx.createAnimation({timingFunction:'ease'});
anim.rotate('720').step({duration:500});
anim.translateY('100px').step({duration:500});
anim.translateX('100px').step({duration:500});
this.setData({animData:anim.export()});}});

9)绘图:

在<canvas/>组件中画图必须通过API实现。<canvas/>中存在一个二维坐标系,左上角坐标为(0,0),所有绘图API都会基于这个坐标系进行绘图。绘图过程大致分为3步:创建执行上下文;通过执行上下文进行绘制描述;调用绘图API,将绘制描述到<canvas/>。示例:
<canvas canvas-id='myCanvas" style="width:200rpx;height:200rpx;border:solid 1px" />
Page({onReady:function(){var canvasContext=wx.createCanvasContext('myCanvas');
canvasContext.setFillStyle('red');
canvasContext.fillRect(10,10,110,110);
canvasContext.draw();}});
①基础API:
⑴wx.createCanvasContext(canvasId):
在绘图需要调用wx.createCanvasContext()创建一个绘图上下文context对象,一个canvasContext通过canvasId与<canvas/>一一绑定,canvasContext仅作用于对应的<canvas/>,通过调用绘图上下文相关方法实现绘图功能。示例
var context=wx.createCanvasContext('myCanvas');
⑵wx.canvasToTempFilePath(Object):
将当前画布内容导出生成图片,并返回文件路径。Object参数的属性有:
·canvasId:画布标识,指定导出哪个画布,传入定义在<canvas/>的canvas-id
·success:接口调用成功的回调函数,返回参数属性有tempFilePath,是导出图片的路径
·fail:接口调用失败的回调函数
·complete:接口调用结束的回调函数,无论调用成功或失败都会执行
示例:
wx.canvasToTempFilePath({canvasId:'myCanvas',
success:function(res){console.log(res.tempFilePath);}});
⑶save():保存当前的绘图上下文,每次保存时将当前设置进行压栈,可以用于保存一些默认设置,需要注意的是save()方法仅用于保存当前绘图上下文状态,而不是用于保存当前操作步骤。
⑷restore():恢复之前保存的绘图上下文。
⑸draw(reserve):将之前在绘图上下文中的描述(路径、变形、样式)画到canvas中。参数reserve非必填,为false时,本次调用drawCanvas绘制之前native层应先清空画布再继续绘制;值为true则保留当前画布上的内容,本次调用drawCanvas绘制的内容覆盖在上面,默认为false。
<canvas/>所有绘图行为都需要调用绘图上下文相关方法实现,这些方法整体可分为10类:样式、渐变、线条样式、矩阵、路径、变形、文字、图片、混合等。
②样式设置:
样式设置会作用于全局,如果没有覆盖,后续绘图的颜色将沿用之前的设置。样式设置相关方法有几种。
⑴setFillStyle(color):
设置填充颜色,没有设置默认black,参数color设置填充样式的颜色,可为颜色字符串,取值'rgb(255,0,0)'、'rgba(255,0,0,0.6)'、'#ff0000'格式的颜色字符串,也可以为渐变颜色对象
⑵setStrokeStyle(color):
设置描边颜色,参数color同上。
⑶setShadow(offsetX,offsetY,blur,color):
设置阴影,有几个参数:
·offsetX:阴影相对于形状在水平方向的偏移
·offsetY:阴影相对于形状在垂直方向的偏移
·blur:阴影的模糊级别,数值越大越模糊
·color:阴影的颜色,取值为'rgb(255,0,0)'、'rgba(255,0,0,0.6)'、'#ff0000'格式的颜色字符串
示例:
<canvas canvas-id='myCanvas" style="width:100%;height:400px;" />
Page({onReady:function(){var canvasContext=wx.createCanvasContext('myCanvas');
canvasContext.setFillStyle('red');
canvasContext.fillRect(10,10,50,50);
canvasContext.setStrokeStyle('#0000ff');
canvasContext.strokeRect(70,10,50,50);
canvasContext.setShadow(10,10,50,'rgb(0,255,0)');
canvasContext.fillRect(130,10,50,50);
canvasContext.draw();}});
③创建渐变:
渐变相关方法用于创建渐变对象,渐变对象可作为参数传入绘图相关方法,创建渐变的坐标是基于<canvas/>的坐标,而不是被填充图形的坐标,在使用渐变填充图像时要注意坐标的转化。
⑴createLinearGradient(x0,y0,x1,y1):
创建一个线性渐变,参数有:
·x0:起点的x坐标
·y0:起点的y坐标
·x1:终点的x坐标
·y1:终点的y坐标
⑵createCircularGradient(x,y,r):
创建一个圆形渐变,起点在圆心,终点在圆环,参数有:
·x:圆心的x坐标
·y:圆心的y坐标
·r:圆的半径
⑶addColorStop(stop,color):
创建一个颜色渐变点,参数有:
·stop:表示渐变点在起点和终点中的位置,取值范围0~1
·color:渐变点的颜色,取值为'rgb(255,0,0)'、'rgba(255,0,0,0.6)'、'#ff0000'格式的颜色字符串
示例:
<canvas canvas-id='myCanvas" style="width:100%;height:400px;" />
Page({onReady:function(){var canvasContext=wx.createCanvasContext('myCanvas'),
linearGradient,circularGradient,colorStop;
linearGradient=canvasContext.createLinearGradient(0,0,100,0);
linearGradient.addColorStop(0,'black');
linearGradient.addColorStop(1,'red');
canvasContext.setFillStyle(linearGradient);
canvasContext.fillRect(10,10,100,100);

circularGradient=canvasContext.createCircularGradient(170,60,50);
circularGradient.addColorStop(0,'red');
circularGradient.addColorStop(0.16,'orange');
circularGradient.addColorStop(0.33,'yellow');
circularGradient.addColorStop(0.5,'green');
circularGradient.addColorStop(0.66,'cyan');
circularGradient.addColorStop(0.83,'blue');
circularGradient.addColorStop(1,'purple');
canvasContext.setFillStyle(circularGradient);
canvasContext.fillRect(120,10,100,100);
canvasContext.draw();}});
④设置线条样式:
线条样式设置会作用于全局,如果没有覆盖,后续绘图的设置将沿用之前的设置。
⑴setLineWidth(lineWidth):
设置线条的宽度,默认线条宽度为1px,参数lineWidth为线条的宽度,单位px
⑵setLineCap(lineCap):设置线条结束端点样式,默认结束端点样式为square,参数lineCap为线条结束端点样式,取值有square、butt、round,分别表示端点样式正方形且不会截取线条宽度、端点样式为正方形且会截取线条宽度、端点样式为圆形且不会截取线条宽度。
⑶setLineJoin(lineJoin):设置线条的交点样式,默认交叉点样式为miter。参数lineJoin为线条结束交叉点样式,取值有bevel、round、miter,分别为平角、圆角、尖角。
⑷setMiterLimit():设置最大斜接长度,斜接长度指的是在两条线交汇处内角和外角之间的距离,当setLineJoin为miter时才有效。超过最大倾斜长度时,连接处将以lineJoin为bevel来显示,参数miterLimit为最大斜接长度。
示例:
<canvas canvas-id='myCanvas" style="width:100%;height:700px;" />
var _fn;
Page({onReady:function(){var canvasContext=wx.createCanvasContext('myCanvas');
canvasContext.setLineWidth(10);
canvasContext.setLineCap('square');
_fn.drawLine(canvasContext,[10,20],[150,20]);
canvasContext.setLineCap('butt');
_fn.drawLine(canvasContext,[10,40],[150,40]);
canvasContext.setLineCap('round');
_fn.drawLine(canvasContext,[10,60],[150,60]);
canvasContext.setLineCap('square');
canvasContext.setLineJoin('bevel');
_fn.drawAngle(canvasContext,[10,80]);
canvasContext.setLineJoin('miter');
canvasContext.setMiterLimit(1);
_fn.drawAngle(canvasContext,[10,140]);
canvasContext.draw();}});
_fn={drawLine:function(canvasContext,start,end){
canvasContext.beginPath();
canvasContext.moveTo(start[0],start[1]);
canvasContext.lineTo(end[0],end[1]);
canvasContext.stroke();},
drawAngle:function(canvasContext,beginPoint){
canvasContext.beginPath();
canvasContext.moveTo(beginPoint[0],beginPoint[1]);
canvasContext.lineTo(beginPoint[0]+40,beginPoint[1]+20);
canvasContext.lineTo(beginPoint[0],beginPoint[1]+40);
canvasContext.stroke();}}
⑤矩形方法:
⑴rect(x,y,width,height):
创建一个矩形,创建后需要调用fill()或stroke()方法将矩形画到<canvas/>中。参数为:
·x:矩形路径左上角的x坐标
·y:矩形路径左上角的y坐标
·width:矩形路径的宽度
·height:矩形路径的高度
⑵fillRect(x,y,width,height):
填充一个矩形,填充时需要调用setFillStyle()设置颜色,默认黑色。参数为:
·x:矩形路径左上角的x坐标
·y:矩形路径左上角的y坐标
·width:矩形路径的宽度
·height:矩形路径的高度
⑶strokeRect(x,y,width,height):
画一个非填充的矩形,绘制前需要调用setFillStyle()设置颜色,默认黑色。参数为:
·x:矩形路径左上角的x坐标
·y:矩形路径左上角的y坐标
·width:矩形路径的宽度
·height:矩形路径的高度
⑷clearRect(x,y,width,height):
清除画布上在该区域内的内容,清除后会直接显示出<canvas/>背景色。参数为:
·x:矩形路径左上角的x坐标
·y:矩形路径左上角的y坐标
·width:矩形路径的宽度
·height:矩形路径的高度
示例:
<canvas canvas-id='myCanvas" style="width:100%;height:700px;" />
Page({onReady:function(){var canvasContext=wx.createCanvasContext('myCanvas');
canvasContext.rect(10,10,30,30);
canvasContext.stroke();
canvasContext.draw();
canvasContext.fillRect(10,50,30,30);
canvasContext.draw(true);}}); //传入参数true表示接着上次继续绘制
⑥路径绘制:
路径绘制并不会在画布上绘制形状,创建后可被stroke()绘制线条,也可以被fill()填充区域。绘制路径开始时需要调用beginPath()方法,结束时需要调用closePath()方法,通过路径方法组合,可以绘制任何形状图形。
⑴beginPath():开始创建一个路径,需要调用fill或stroke才会使用路径进行填充或描边
⑵closePath():关闭一个路径,关闭路径会连接起点和终点。如果关闭路径后没有调用fill或stroke就开启了新路径,之前的路径不会被渲染
⑶fill():对当前路径中的内容进行填充,默认填充色为黑。如果当前路径没有闭合,fill方法会将起点和终点进行连接然后填充。fill填充的路径从beginPath开始计算
⑷stroke():画出当前路径的边框,默认黑色。stroke描绘的路径从beginPath开始计算
⑸moveTo(x,y):把路径移动到画布中的指定点,但不创建线条,参数x、y为目标位置的x、y坐标
⑹lineTo(x,y):添加一个新点,然后在画布中创建到该点的路径。参数同上。
⑺arc(x,y,r,sAngle,eAngle,counterclockwise):添加一个弧形路径到当前路径,顺时针绘制。参数为:
·x:圆的x坐标
·y:圆的y坐标
·r:圆的半径
·sAngle:起始弧度
·eAngle:终止弧度
·counterclockwise:可选,指定弧度方向是顺时针或逆时针,默认false,即顺时针
⑻quadraticCurveTo(cpx,cpy,x,y):创建二次方贝塞尔曲线,曲线的起始点为路径中前一个点,参数为:
·cpx:贝塞尔控制点的x坐标
·cpy:贝塞尔控制点的y坐标
·x:结束点的x坐标
·y:结束点的y坐标
⑼bezierCurveTo(cp1x,cp1y,cp2x,cp2y,x,y):创建三次方贝塞尔曲线,曲线的起始点为路径中前一个点。参数为:
·cp1x:第一个贝塞尔控制点的x坐标
·cp1y:第一个贝塞尔控制点的y坐标
·cp2x:第二个贝塞尔控制点的x坐标
·cp2y:第二个贝塞尔控制点的y坐标
·x:结束点的x坐标
·y:结束点的y坐标
示例:
<canvas canvas-id='myCanvas" style="width:100%;height:700px;"></canvas>
var _fn;
Page({onReady:function(){var context=wx.createCanvasContext('myCanvas');
_fn.drawTrianglePath(context,[10,60]);
context.stroke();
context.draw();
_fn.drawSectorPath(context,[60,10],55,0,60);
context.setStrokeStyle('black');
context.setLineWidth(5);
context.setFillStyle('gray');
context.stroke();
context.fill();
context.draw(true);
context.setLineWidth(1);
_fn.drawQuadraticCurve(context,[10,70],[10,170],[100,70]);
context.stroke();
context.draw(true);
_fn.drawBezierCurve(context,[110,70],[110,150],[210,150],[210,70]);
context.stroke();
context.draw(true);}});
_fn={drawTrianglePath:function(canvasContext,beginPos){
canvasContext.moveTo(beginPos[0],beginPos[1]);
canvasContext.beginPath();
canvasContext.lineTo(beginPos[0]+30,beginPos[1]-50);
canvasContext.lineTo(beginPos[0]+60,beginPos[1]);
canvasContext.lineTo(beginPos[0],beginPos[1]);
canvasContext.closePath();},
drawSectorPath:function(canvasContext,beginPos,radius,startAngle,endAngle){
canvasContext.moveTo(beginPos[0],beginPos[1]);
canvasContext.beginPath();
canvasContext.lineTo(beginPos[0]+radius,beginPos[1]);
canvasContext.arc(beginPos[0],beginPos[1],radius,startAngle*Math.PI/180,endAngle*Math.PI/180);
canvasContext.lineTo(beginPos[0],beginPos[1]);
canvasContext.closePath();},
drawQuadraticCurve:function(canvasContext,startPoint,controlPoint,endPoint){
canvasContext.beginPath();
canvasContext.moveTo(startPoint[0],startPoint[1]);
canvasContext.quadraticCurveTo(controlPoint[0],controlPoint[1],endPoint[0],endPoint[1]);},
drawBezierCurve:function(canvasContext,startPoint,controlPoint1,controlPoint2,endPoint){
canvasContext.beginPath();
canvasContext.moveTo(startPoint[0],startPoint[1]);
canvasContext.BezierCurveTo(controlPoint1[0],controlPoint1[1],controlPoint2[0],controlPoint2[1],endPoint[0],endPoint[1]);}}
⑦变形:
变形相关方法会整体影响之后绘图方法的坐标系,每个方法之前可以相互迭代,可以认为变形是对整体坐标系的变形。
⑴scale(scaleWidth,scaleHeight):在调用scale方法后,之后创建的路径其纵横坐标会被缩放,可认为是对画布整体进行了缩放,参数为:
·scaleWidth:横坐标轴缩放的倍数(1=100%,0.5=50%,2=200%)
·scaleHeight:纵坐标轴缩放的倍数(1=100%,0.5=50%,2=200%)
⑵rotate(rotate):以原点为中心,原点可以用translate方法修改。顺时针旋转当前坐标轴,多次调用rotate,旋转的角度会叠加。参数为:
·rotate:旋转角度,单位弧度
⑶translate(x,y):对当前坐标系的原点(0,0)进行变换,默认的坐标系原点为页面左上角,参数为:
·x:水平坐标平移量
·y:垂直坐标平移量
示例:
<canvas canvas-id='myCanvas" style="width:100%;height:200px;" ></canvas>
<button bindtap="scale">坐标放大2倍</button>
<button bindtap="rotate">旋转30度</button>
<button bindtap="translate">原点坐标x、y均加10px</button>
<button bindtap="drawReact">绘制正方形</button>
Page({canvasContext:null,
onReady:function(){this.canvasContext=wx.createCanvasContext('myCanvas');},
translate:function(){this.canvasContext.rotate(30*Math.PI/180);},
rotate:function(){this.canvasContext.rotate(30*Math.PI/180);},
scale:function(){this.canvasContext.acale(2,2);},
drawReact:function(){var context=this.canvasContext;
context.restore();
context.rect(0,0,15,15);
context.stroke();
context.draw(true);}});
⑧文字:
文字相关方法能将文字输出到画布中,字体颜色能通过setFillStyle()方法修改。文字方法有:
⑴fillText(text,x,y):
用于在画布上绘制被填充的文本。参数有:
·text:在画布上输出的文本
·x:绘制文本的左上角x坐标位置
·y:绘制文本的左上角y坐标位置
⑵setFontSize(fontSize):设置字体的字号。参数fontSize为字体的字号
示例:
<canvas canvas-id='myCanvas" style="width:100%;height:200px;" ></canvas>
Page({onReady:function(){var context=wx.createCanvasContext('myCanvas');
context.fillText('中文',10,20);
context.setFontSize(24);
context.setFillStyle('red');
context.fillText('English',100,20);
context.draw();}});
⑨图片:
图片方法只有一个drawimage(imageResource,x,y,width,height),用于在画布上绘制图片。属性有:
·imageResource:所要绘制的图片资源,可以是网络资源,也可以是本地资源相对路径
·x:图像左上角的x坐标
·y:图像左上角的y坐标
·width:图像宽度
·height:图像高度
示例:
<canvas canvas-id='myCanvas" style="width:100%;height:200px;" ></canvas>
Page({onReady:function(){var context=wx.createCanvasContext('myCanvas');
context.drawImage('http://www.qq1234.org/uploads/allimg/14/38277.jpg',1,1,100,131);
context.draw();}});
⑩混合:
混合方法只有一个setGlobalAlpha(alpha)方法,设置全局画笔透明度,参数alpha为透明度,0表示完全透明,1表示完全不透明。

10)开放接口:

①登录:
在小程序中,登录分为2步,第一步需要获取登录凭证,第二步用登录凭证获取用户登录态信息,登录态信息可用于后续支付等流程。
⑴wx.login(Object):
调用接口获取登录凭证code,进而换取用户登录态信息,包括用户唯一表示openid及本次登录的会话密钥session_key,用户数据的加解密通信需要依赖会话密钥完成。Object属性有:
·success:接口调用成功的回调函数,返回的参数包括errMsg--调用结果;code--用户允许登录后,回调内容会带上code,有效期5分钟,开发者需要将code发送到开发者服务器后台,使用code换取session_key。
·fail:接口调用失败的回调函数
·complete:接口调用结束的回调函数,调用成功、调用失败都会执行
示例:
wx.login({success:function(res){if(!res.code){return;}
wx.request({url:'https://myserver.com/login',
data:{code:res.code},
success:function(loginInfo){console.log('登录成功');}});}});
⑵code换取session_key:
调用wx.login()获取code后,需要在5分钟内用code换取session_key、openid等用户信息,为此官方有个接口。由于session_key是对用户数据进行加密签名的密钥,为了自身应用安全,尽量使用后台服务器调用这个接口,保存登录信息,返回给小程序前台,接口地址:
https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code
接口参数:
·appid:小程序唯一标识,在开发者后台“设置--开发设置”中可找到
·secret:小程序的app secret,在开发者后台“设置--开发设置”中可找到
·js_code:调用wx.login()登录时获取的code
·grant_type:填写为“authorization_code”
接口返回参数:
·openid:用户唯一标识
·session_key:会话密钥
·expires_in:会话有效期,以秒为单位,如2592000代表会话有效期30天
示例:
{"openid":"OPENID","session_key":"SESSIONKEY","expires_in":2592000} //正常返回的数据包
{"errcode":40029,"errmsg":"invalid code"} //错误时返回的数据包一种
⑶登录态维护:
开发中,每个项目应该利用后台自己维护登录态,不能直接把session_key、openid等字段作为用户的标识或者session的标识。
⑷wx.checkSession(Object):
检查登录态是否过期。Object参数属性有:
·success:接口调用成功的回调函数,登录态未过期
·fail:接口调用失败的回调函数,登录态已过期
·complete:接口调用结束的回调函数,调用成功、调用失败都会执行
②用户信息:
wx.getUserInfo(Object)用于获取用户信息,需要首先调用wx.login接口。Object参数属性有:
·success:接口调用成功的回调函数,success返回参数属性包括userInfo--用户信息对象,不包含openid等敏感信息;rawData--不包含敏感信息的原始数据字符串,用于计算签名;signature--使用sha1(rawData+sessionkey)得到的字符串,用于校验用户信息;encryptData--包括敏感数据在内的完整用户信息的加密数据;iv--加密算法的初始向量。
·fail:接口调用失败的回调函数,登录态已过期
·complete:接口调用结束的回调函数,调用成功、调用失败都会执行
示例:
wx.getUserInfo(res){console.log(res);}});
对encryptData解密后可得到完整的用户信息,解密算法可参考网页:
https://mp.weixin.qq.com/debug/wxadoc/dev/api/signature.html
解压后的结构为:
{"openid":"OPENID","nickName":"NICKNAME","gender":"GENDER","city":"CITY","province":"PROVINCE","country":"COUNTRY","avatarUrl":"AVATARURL","unionId":"UNIONID","watermark":{"appid":"APPID","timestamp":TIMESTAMP}}
其中,unionId用于区分不同应用下的用户身份,它在同一个微信开放平台账号下的移动应用、网站应用和公共账号是全局唯一的,而openId只在同一应用体系是唯一的,即在不同公共账号下的openId可能重复,但unionId不会重复。即同一个用户,对同一个微信开放平台下的不同应用,登录后unionId是相同的,openId是不同的。
获取unionId首先需要将小程序接入微信开放平台,开发者可以登录微信开放平台,进入“管理中心-公众账号-绑定公众账号”,添加账号。
③微信支付:
wx.requestPayment(Object)用于发起微信支付。Object参数属性有:
·timestamp:当前的时间戳
·nonceStr:随机字符串,长度为32个字符以下
·package:统一下单接口返回的prepay_id参数值,提交格式prepay_id=*
·signType:签名算法,暂支持MD5
·paySign:签名
·success:接口调用成功的回调函数
·fail:接口调用失败的回调函数
·complete:接口调用结束的回调函数,调用成功、调用失败都会执行
④模板消息:
最常见的模板消息就是通过微信支付后,微信支付推送的支付消息。在小程序中也能使用模板消息给用户推送信息。低版本不支持。
⑴调用模板消息接口:
发送模板消息需要通过POST方式调用微信后台接口,接口调用可以是前台调用,也可以是后台调用,接口地址为:https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send? access_token=ACCESS_TOKEN
post参数有:
·touser:接收者(用户)的openid,通常是当前使用者的openid,必填
·template_id:所需下发的模板消息的id,必填
·page:点击模板卡片后的跳转页面,仅限小程序内的页面,支持带参数
·form_id:必填,表单提交场景下,为submit事件带上formId;支付场景下,为本次支持的prepay_id
·data:模板内容,不填则下发空模板,data中keyword对应模板keyword,必填
·color:模板内容字体的颜色,不填默认黑色
·emphasis_keyword:模板需要放大的关键词,不填则默认无放大
示例:
{"touser":"OPENID","template_id":"TEMPLATE_ID","page":"index","form_id":"FORMID",
"data":{"keyword1":{"value":"薯片","color":"#173117"},
"keyword2":{"value":"2015年01月05日 12:30","color":"#173177"}},
"emphasis_keyword":"keyword1.DATA"}
接口返回数据:{"errcode":0,"errmsg":"ok"}
返回数据中常见错误有:
·40037:template_id不正确
·41028:form_id不正确,或者过期
·41029:form_id已被使用
·41030:page不正确
·45009:接口调用超过限额,目前默认每个账号日调用限额为100万
⑵调用模板消息时有几个关键参数:
◆template_id和data:
template_id是需要调用模板的id,data为当前模板所需要的数据。小程序所有模板都在微信公共平台中模板消息中进行管理,template_id可在模板管理界面中直接复制。
没有模板时可以创建一个新模板,微信定制了多种类型的模板,每个模板可以选取需要填写哪些key值,这些key值会根据请求参数data属性进行填写,选取好后会生成相应的模板。
◆form_id:
form_id的值由页面<form/>组件submit方法生成,获取时需要将<form/>的report-submit属性值为true,此时点击提交按钮触发submit事件时,可通过参数获取。示例:
<form report-submit bindsubmit="submit"><button form-type="submit">提交</button></form>
Page({submit:function(e){console.log(e.detail.formId);}});
当用户完成支付行为时,form_id的值应为统一下单接口返回的prepay_id。
◆access_token:
access_token是全局唯一的接口调用凭证,调用很多接口都需要使用access_token。access_token存储至少需要512个字符空间,获取access_token需要通过GET方式调用微信后台接口:https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID &secret=APPSECRET
参数包括:
·grant_type:接口类型,获取access_token时填写client_credential,必填
·appid:第三方用户唯一凭证,即小程序appid,可在微信公众平台的开发设置中获取
·secret:第三方用户唯一凭证密钥,即appsecret,可在微信公众平台的开发设置中获取
⑶获取access_token的操作:
正常情况下,微信会返回JSON数据:{"access_token":"ACCESS_TOKEN","expires_in":7200}
返回的expires_in指凭证的有效时间,单位秒,所以access_token的有效时间为2小时,失效后需要定时刷新。重复刷新将导致上次获取的access_token失效,同时每天调用access_token接口次数有限制。通常利用中控服务器单独维护access_token,系统所有服务都依赖这个服务获取access_token,这样能保证access_token的一致性和有效生命周期。
为了保密appsecret,第三方需要一个access_token获取和刷新的中控服务器,其他业务逻辑服务器所使用的access_token均来自该中控服务器,不应该各自去刷新,否则会造成access_token覆盖而影响业务。目前access_token的有效期通过返回的expires_in来传达,目前是7200秒之内的值,而中控服务器需要根据这个有效时间提前去刷新新access_token。在刷新过程中,中控服务器对外输出依然是老access_token,此时公众平台后台会保证在刷新短时间内,新老access_token都可用,保证第三方业务的平滑过渡。access_token的有效时间可能会在未来调整,所以中控服务器不仅需要内部定时器主动刷新,还需要提供被动刷新access_token接口,便于业务服务器在API调用获知access_token已超时的情况下,可以触发access_token的刷新流程。
⑷调用模板消息的条件:
调用模板消息按类型分为支付和提交表单。当用户在小程序内完成过支付行为,可允许开发者向用户在7天内推送有限条数的模板消息,一次支付可下发1条。当用户在小程序内发生过提交表单行为,且该表单声明为要发模板消息的,开发者需要向用户提供服务时,可允许开发者向用户在7天内推送有限条数的模板消息,一次提交表单可下发1条。
⑸模板管理规则:
新建的模板需要通过审核才能使用。规则包括:标题不能存在相同,标题意思不能存在过度相似,标题必须以“提醒”或“通知”结尾,标题不能带特殊符号、个性化字词等没有行业通用性的内容,标题必须能体现具体服务场景,标题不能涉及营销相关内容,如消费优惠、购物返利、商品更新、优惠券、代金券、红包、会员卡、积分、活动等。
同一标题下,关键词不能存在相同,不能存在过度相似,关键词不能带有特殊符号、个性化字词等没有行业通用性的内容,关键词内容示例必须与关键词对应匹配,关键词不能太过宽泛,需要有限制性。
模板消息不允许恶意诱导用户进行触发操作,不允许恶意骚扰,不允许恶意营销,不允许通过服务号下发模板来告知用户在小程序内触发的服务相关内容。
⑤客服消息:
在小程序中,通过点击<contact-button/>可以进入客服会话系统。在会话系统中,用户发送的消息,微信服务器会将消息的数据包以POST方式传递给开发者填写的URL。当开发者服务器接收到消息后,可以使用发送服务消息接口进行异步回复,这两个行为分别是2个不同的请求。基于这个特性,可以自己研发或接入任何客服系统。
⑴接入指引:
接入微信小程序消息服务需要两步,首先填写开发者服务器配置,开发者服务器接收请求并返回指定信息,验证服务器地址有效性。
要登录微信公众平台,在“设置-消息推送”中启动消息服务,配置页面需要填写URL、Token、EncodingAESKey,其中URL为开发者服务器接收消息的接口URL地址,必须是http://或https://开头,分别支持80和443端口;Token为用户身份令牌,用作生成签名,由开发者设定;EncodingAESKey由开发者手动填写或随机生成,用作消息体加解密密钥。配置页面中可以选择消息加密方式和数据格式,加密方式默认为明文,数据格式默认XML。
提交配置信息后,微信服务器将发送GET请求到填写的服务器地址,开发者服务器收到请求并按要求返回才能完成接入,所以需要配置前先完成后台服务器的接口工作。GET参数有:
·signature:微信加密签名,结合了开发者填写的token参数和请求中的timestamp参数、nonce参数
·timestamp:时间戳
·nonce:随机数
·echostr:随机字符串
后台可通过检验signature验证请求。收到GET请求后,开发者服务器需要原样返回echostr参数内容,才能接入生效。加密/校验是需要将token、timestamp、nonce三个参数进行字典序排序,然后拼接成一个字符串进行sha1加密,开发者获得加密后的字符串可与signature对比,标识该请求来源于微信。完成URL有效性验证后便接入生效。通过配置URL接口,开发者服务器可接受微信服务器推送过来的消息和事件,并根据业务进行响应。
⑵接受消息和事件:
当点击<contact-button/>时便进入了客服会话状态,在会话中开发者服务器接收消息和发送消息是2个不同接口。当用户在客服会话中发送消息,微信服务器会将消息的数据包以POST方式发送到开发者填写的URL。
接收到消息后,开发者服务器必须做出回复,直接回复success,或直接回复空串,告知微信服务器我方服务器已成功接收消息。
微信服务器在5秒内收不到任何响应会断掉连接,并重新发起请求,总共重试3次。重试的消息排重,有msgid的消息推荐使用msgid,事件类型消息推荐使用FromUserName+CreatTime排重。
一旦遇到开发者在5秒内未回复任何内容,或开发者回复了异常数据,微信会在小程序会话中向用户发出系统提示“该小程序客服暂时无法提供服务,请稍候再试”。如果希望增加消息安全性,可以在消息配置中开启消息加密功能,用户发给小程序的消息以及小程序被动回复用户消息都会继续加密。接收的消息按类型划分为进入会话事件、文本消息、图片消息三类。
◆进入会话事件:
当用户点击小程序“客服会话按钮”进入客服会话时将产生的XML数据包格式:
<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreatTime><![CDATA[1482048670]]></CreatTime>
<MsgType><![CDATA[event]]></MsgType>
<Event><![CDATA[user_enter_tempsession]]></Event>
<SessionFrom><![CDATA[sessionFrom]]></SessionFrom>
</xml>
JSON格式:
{"ToUserName":"toUser","FromUserName":"fromUser","CreateTime":1482048670,
"MsgType":"event","Event":"user_enter_tempsession","SessionFrom":"sessionFrom"}
其中:
·ToUserName:小程序的原始ID
·FromUserName:发送者的openid
·CreateTime:事件创建时间
·MsgType:event
·Event:事件类型,user_enter_tempsession
·SessionFrom:开发者在客服会话按钮设置的sessionFrom参数
◆文本消息:
用户在客服会话中发送文本消息时将产生数据包为:
<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreatTime><![CDATA[1482048670]]></CreatTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[this is a test]]></Content>
<MsgId>1234567890123456</MsgId>
</xml>
JSON格式:
{"ToUserName":"toUser","FromUserName":"fromUser","CreateTime":1482048670,
"MsgType":"text","Content":"this is a test","MsgId":"1234567890123456"}
其中:
·Content:文本消息内容
·MsgId:消息id,64位整数
◆图片消息:
用户在客服会话中发送图片消息时产生的数据包为:
<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreatTime><![CDATA[1482048670]]></CreatTime>
<MsgType><![CDATA[image]]></MsgType>
<PicUrl><![CDATA[this is a url]]></PicUrl>
<MediaId><![CDATA[media_id]]></MediaId>
<MsgId>1234567890123456</MsgId>
</xml>
JSON格式:
{"ToUserName":"toUser","FromUserName":"fromUser","CreateTime":1482048670,
"MsgType":"image","PicUrl":"this is a url","Media_id":"media_id",
"MsgId":"1234567890123456"}
其中:
·PicUrl:图片链接,由系统生成
·MediaId:图片消息媒体id,可以调用获取临时素材接口拉取数据
·MsgId:消息id,64位整数
⑶发送消息:
开发者在接收到微信服务器消息后,在一段时间内(目前为48小时)可以调用客服接口,通过POST一个JSON数据包来给用户发送消息。此接口主要用于人工消息处理。目前允许的动作列表如下:


用户动作

允许下发条数限制

下发时限

用户通过客服消息按钮进入会话

1条

1分钟

用户发送消息

3条

48小时

不同动作触发后,允许客服接口下发消息条数和下发时限不同。下发条数达到上限后,会收到错误返回码。发送消息直接通过POST方式调用下面的接口:
https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=ACCESS_TOKEN
消息JSON数据格式为:
{"touser":"OPENID","msgtype":"text","text":{"content":"Hello World"}} //文本消息
{"touser":"OPENID","msgtype":"image","image":{"media_id":"MEDIA_ID"}} //图片消息
请求接口后微信服务器将返回调用结果,其返回错误码为:
·-1:系统繁忙
·0:请求成功
·40001:获取access_token时AppSecret错误,或access_token无效
·40002:不合法的凭证类型
·40003:不合法的OpenId
·45015:回复时间超过限制
·45047:客服接口下行条数超过上限
·48001:API功能未授权
⑷临时素材接口:
在发送消息时,media_id需要填写临时素材id。临时素材需要先调用新增临时素材接口上传至微信服务,在通过获取接口获取对应资源id。目前小程序只支持下载图片文件。
通过新增素材接口可以把本地媒体文件(目前只支持图片)上传至微信服务器,用于用户发送客服消息或被动回复用户消息。接口请求为POST/FORM,调用接口为:
https://api.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE
其中:
·access_token:调用接口凭证,必填
·type:image,必填
·media:form-data中媒体文件标识,有filename、filelength、content-type等消息
示例:利用curl命令,用FORM表单方式上传一个多媒体文件
curl -F media=@test.jpg https://api.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS _TOKEN&type=TYPE
调用后正常情况会返回以下JSON数据:
{"type":"TYPE","media_id":"MEDIA_ID","created_at":123456789}
错误情况会返回以下形式JSON数据:
{"errcode":40004,"errmsg":"invalid media type"}
通过调用获取临时素材接口,可以获取已上传的临时文件,目前小程序仅支持下载图片文件。调用接口为POST/FORM,调用接口为:https://api.weixin.qq.com/cgi-bin/media/ get?access_token=ACCESS_TOKEN&media_id=MEDIA_ID
示例:使用curl命令获取多媒体文件
curl -I -G "https://api.weixin.qq.com/cgi-bin/media/get?access_token=ACCESS_TOKEN& media_id=MEDIA_ID"
调用成功后,正常情况将返回HTTP头为:
HTTP/1.1 200 OK
Connection:close
Content-Type: image/jpeg
Content-disposition: attachment; filename="MEDIA_ID.jpg"
Date: Sun, 06 Jan 2013 10:20:18 GMT
Cache-Control: no-cache, must-revalidate
Content-Length: 339721
如果返回的是视频素材,内容如下:
{"video_url":DOWN_URL}
错误情况将返回JSON:
{"errcode":40007,"errmsg":"invalid media_id"}
⑥分享:
小程序分享页面需要在Page中定义onShareAppMessage函数,设置该页面分享信息。只有定义了此事件函数,右上角才会显示“分享”按钮。用户点击分享按钮时会触发该函数,该函数返回的Object对象将用于定义分享内容,目前分享图片不能自定义,系统会取当前页面,从顶部开始,高度为80%屏幕高度的图像作为分享图片。返回Object属性有:
·title:分享标题,默认值为当前小程序名称
·desc:分享描述,默认值为当前小程序名称
·path:分享路径,必须是以“/”开头且在app.json中已注册的路径,默认为当前页面path
示例:
Page({onShareAppMessage:function(){
return{title:'自定义分享标题',desc:'自定义分享描述',path:'/page/home?tab=cart'}}});
⑦获取二维码:
小程序也可以通过调用后台接口生成任意页面对应二维码,扫描该二维码即可直接进入小程序对应页面。通过该接口,仅能生成已发布小程序的二维码。
在开发过程中,可在开发工具预览时生成开发版的带参二维码。带参二维码只有10000个,请谨慎使用。接口请求方式为POST,接口地址为:
https://api.weixin.qq.com/cgi-bin/wxaapp/createwxaqrcode?access_token=ACCESS_TOKEN
其中:
·path:页面路径,不能为空,最大长度128字节
·width:二维码的宽度,默认值430

Copyright@dwenzhao.cn All Rights Reserved   备案号:粤ICP备15026949号
联系邮箱:dwenzhao@163.com  QQ:1608288659