微信小程序
一、创建项目
1、准备工作
微信公众平台注册开发者账号:https://mp.weixin.qq.com/
下载小程序开发工具:
https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html
2、认识项目目录
1.pages目录:用于存放所有的页面。
2.utils目录:用于存放工具类文件。
3.app.js:是入口文件,程序在运行时,首先要执行该文件。
4.app.json:是全局配置文件,用于配置小程序的信息(它里面配置的是全局信息)。
5.app.wxss:是全局样式文件。全局样式文件里面定义的选择器,在所有的页面中生效。
6.project.config.json:是项目配置文件。
7.sitemap.json:是SEO配置文件,方便用户搜索到该小程序。
(1)pages配置项
pages里面注册的是视图。用于指定小程序由哪些页面组成,每一项都对应一个页面的路径(含文件名)信息。
??"pages":[
????"pages/index/index"
??]
(创造包含.js .json .wxml .wxss后缀的文件的同名文件夹
(2)window配置项
window 是全局窗口配置。
1.backgroundTextStyle 设置文本样式(下拉loading的样式),仅支持 dark / light。
2.navigationBarBackgroundColor 设置导航栏背景。
3.navigationBarTitleText 设置导航栏文本。
4.navigationBarTextStyle 设置导航栏标题颜色,仅支持 black / white。
写法:
"window":{
????"backgroundTextStyle":"light",
????"navigationBarBackgroundColor":?"#369",
????"navigationBarTitleText":?"KW43-APP",
????"navigationBarTextStyle":"white"
??}
(3)style
style 设置样式级别,默认是v2。
"style":?"v2"
(4)sitemapLocation
sitemapLocation 指明sitemap.json 的位置;默认为 'sitemap.json' 即在 app.json 同级目录下名字的 sitemap.json 文件。
??"sitemapLocation":?"sitemap.json"
3、页面组成
每一个页面由四个文件组成:xxx.wxml文件、xxx.wxss文件、 xxx.js文件和xxx.json文件。
(1)xxx.wxml文件
xxx.wxml文件,就相当于一个html文件。在wxml文件中,不能写传统的html标签,只能写微信提供的组件。
① view组件
相当于div标签。
② text组件
相当于span标签。
③ swiper
swiper是滑块视图容器,它里面只能放swiper-item组件。
swiper组件的常用属性:
circular是衔接滑动
autoplay是自动切换
interval是自动切换时间间隔
indicator-dots是否显示面板指示点
indicator-color指示点颜色
indicator-active-color当前选中的指示点颜色
<swiper?class="swiper"?circular?autoplay?interval="3000"?indicator-dots?indicator-color='#eee'?indicator-active-color='#369'>
</swiper>
④ image
image是图片组件,最好全部采用网络图片,因为小程序的总体积不允许超过2MB。
(2)xxx.wxss文件
xxx.wxss文件,就相当于一个css文件。在wxss文件中,最好不要写标签选择器和id选择器,统一写类选择器。
为了让小程序里面的内容在各种设备上能够自适应显示,微信推出了响应式单位:rpx。在iphone6中,2rpx=1px。
width:?60rpx;?????/*?相当于width:?30px;?*/
(3)xxx.js文件
xxx.js文件,是交互文件(核心文件)。
Page()函数,返回页面对象,该函数需要传一个配置参数,这个配置参数是一个对象。在这个配置对象中,定义当前页面的所有内容。
① data
定义页面的数据。
Page({
data:?{
?????name:?"热门歌曲",
?????songs:?[{id:?1001},?{id:?1002}]
??}
})
② 自定义函数
开发者可以添加任意的函数或数据到Object 参数中,在页面的函数中用this可以访问。
Page({
????//?定义函数
????delSong()?{
????????this.data.songs.splice(0,?1)
????????this.setData({
????????????songs:?this.data.songs
????????})
????}
})
(4)xxx.json文件
xxx.json文件,是页面的配置文件(它里面配置的是当前页面信息)。
5、插值表达式 {{}}
WXML 中的动态数据均来自对应 Page 的 data。
(1)获取data中数据
通过插值表达式{{}},可以显示js里面定义的data里面的数据。
<text>歌曲分类:{{name}}</text>
(2)组件属性(需要在双引号之内)
??<view?id="item-{{id}}">?</view>
(3)运算
可以在{{}} 内进行简单的运算。
① 三元运算
<view?class="item?{{index%2===0???'bg'?:?''}}">?</view>
② 逻辑判断
??<view?wx:if="{{length?>?5}}">?</view>
6、bindtap
bindtap是触屏事件,其实就是相当于网页中的点击事件。
<view?class="btn"?bindtap="delSong">删除</view>
7、data-xxx 自定义属性
小程序中bindtap绑定方法时不能传参数。所以组件通过data-xxx传递数据。
<view?class="btn"?data-index="{{index}}"?bindtap="del1">删除</view>
注意:自定义属性的命名用驼峰或者大写命名,小程序内部会自动转成小写。
del(e){
????//解构出自定义的index属性
????let?{currentTarget:{dataset:{index}}}?=?e
?}
8、setData()方法
setData()方法,更新页面中数据。页面数据更新后,调用setData()方法重新渲染到页面。
???this.setData({
??????typeId:typeid,
??????name:typename
????})
[if !supportLists]二、[endif]列表渲染
1、wx:for
wx:for指令用于循环数组数据,生成组件。
循环出来的每一项通过item返回,每一项对应的索引,通过index返回。
????<view?wx:for="{{songs}}"?wx:key="index"?class="items">
???????<text>{{index}}--{{item.id}}--{{item.name}}</text>
????</view>
2、wx:key
wx:key="",设置每一项唯一的标识。循环列表时,添加wx:key的好处是,将来列表发生变化时重新渲染列表的损耗为更低。
三、条件渲染
条件渲染可以使用wx:if或hidden。
一般来说,wx:if 有更高的切换消耗而 hidden 有更高的初始渲染消耗。因此,如果需要频繁切换的情景下,用 hidden 更好,如果在运行时条件不大可能改变则 wx:if 较好。
1、wx:if
wx:if用于条件渲染:条件为真生成里面的内容,条件为假不会生成里面的内容。(每次重新生成内容)
也可以用wx:elif 和 wx:else 来添加一个 else 块。
??<view?wx:if="{{typeID?==?1}}">?1?</view>
??<view?wx:elif="{{typeID?==?2}}">?2?</view>
??<view?wx:else>?3?</view>
2、hidden
hidden用于条件渲染:条件为真隐藏里面的内容,条件为假显示里面的内容。(每次切换样式)
??<view?hidden="{{typeID!=?2}}">?1?</view>
四、tabBar&页面跳转
1、tabBar
在app.json文件中添加tabBar节点。tabBar是小程序客户端底部或顶部tab栏的实现。
(1)tabBar相关属性
color:tab上的文字默认颜色,仅支持十六进制颜色。
selectedColor:tab上的文字选中时的颜色,仅支持十六进制颜色。
backgroundColor:tab的背景色,仅支持十六进制颜色。
borderStyle:tabbar上边框的颜色, 仅支持 black / white。
position:tabBar的位置,默认值是: bottom,仅支持 bottom / top。当 position 为 top 时,不显示 icon。
custom:自定义tabBar。
"tabBar":?{
????"color":?"#000000",
????"selectedColor":?"#336699",
????"backgroundColor":?"#ffffff",
????"borderStyle":?"black",
????"position":?"bottom"
??}
(2)list
list:tab的列表。
list 接受一个数组,只能配置最少 2 个、最多 5 个 tab。
pagePath:页面路径,必须在pages 中先定义。
text:tab 上按钮文字。
iconPath:图片路径,icon 大小限制为 40kb,建议尺寸为 81px * 81px,不支持网络图片。selectedIconPath:选中时的图片路径,icon 大小限制为 40kb,建议尺寸为 81px * 81px,不支持网络图片。
????"list":?[
??????{
????????"text":?"首页",
????????"pagePath":?"pages/index/index",
????????"iconPath":?"assets/icon/home.png",
????????"selectedIconPath":?"assets/icon/home2.png"
??????},
??????{
????????"text":?"列表",
????????"pagePath":?"pages/list/list",
????????"iconPath":?"assets/icon/list.png",
????????"selectedIconPath":?"assets/icon/list2.png"
??????}
]
2、页面跳转
(1)跳转普通页面
方法① navigator组件
?<!--?跳转到普通页,可以通过返回按钮返回?-->
?<navigator?url="../detail/detail">到详情页</navigator>
方法② navigateTo()方法
navigateTo()方法,用于跳转普通页面。
<view?bindtap="gotoDetail">到详情页</view>
gotoDetail(){
????//使用全局api跳转,navigateTo()方法,用于跳转普通页面
????wx.navigateTo({
??????url:?'../detail/detail',
????})
???}
(2)跳转tabBar页面
方法① navigator组件
如果要使用navigator组件跳转tabBar页面,需要设置open-type="switchTab"。
?<!--?跳转到tabBar页面,不可以通过返回按钮返回。因为跳转到指定的tabBar页面后,会关闭其他所有页面?-->
<navigator?url="../list/list"?open-type="switchTab">到列表页</navigator>??????????????????????????????????????????????????????????????????????????????????????
方法② switchTab()方法
switchTab()方法,用于跳转tabBar页面。
??<view?bindtap="gotoList">到列表页</view>
??gotoList(){
????wx.switchTab({
??????url:?'../list/list',
????})
??}
五、确认框和消息框
1、wx.showModal() 确认框
title:提示的标题
content:提示的内容
success:接口调用成功的回调函数。回调函数中的confirm属性返回true,表示点击的是确定按钮,否则是取消按钮。
?wx.showModal({
??????content:'是否确定删除',
??????success:({confirm})=>{
????????//confirm返回true,表示点击的是确定按钮,否则是取消按钮
????????if(confirm){
??????}
????})?
2、wx.showToast() 显示消息提示框
title:提示的内容
icon:图标
duration:消息提示框的显示时间
mask:是否显示透明蒙层,防止触摸穿透
六、封装方法
??榛锓ㄓ辛街郑孩?commonjs规范,② es6规范。
nodejs环境采用的就是commonjs规范。采用exports 或 module.exports 导出成员,采用require() 导入成员。
微信小程序支持commonjs规范,同时还支持官方的ES6规范。ES6规范采用export 导出成员,采用import 导入成员。
[if !supportLists]1、[endif]封装方法并导出
将封装的方法放到util目录下的js文件中。可以新建js文件,也可以写在直接util.js文件中。
(1)确认框方法
//?定义确认框方法,并导出
export?let?$confirm?=?(content)=>{
??return?new?Promise((resolve)=>{
????wx.showModal({
??????content,
??????success:({confirm})=>{
????????if(confirm){
??????????resolve()
????????}
??????}
????})
??})
}
(2)消息框方法
//?定义消息框方法,并导出
export?let?$msg?=?(title,icon='success',duration=1500)=>{
??wx.showToast({
????title,
????icon,
????duration,
????mask:true
??})
}
(3)获取事件参数的方法
export?let?$key?=?(e)=>{
??return?e.currentTarget.dataset
}
[if !supportLists]2、[endif]导入方法
import是ES6的导入语句。
//?导入msg??橹械闹付ǔ稍?/p>
import?{$msg,$confirm}?from?'../../utils/msg'
[if !supportLists]3、[endif]将方法注册给全局对象wx
wx对象是微信小程序的全局对象,在任何地方都可以使用。
[if !supportLists](1)[endif]注册语句
wx.$msg?=?$msg
wx.$confirm?=?$confirm
[if !supportLists](2)[endif]在app.js入口文件中导入
注意:注册给wx对象的方法,需要在app.js文件中导入,才可使用。
//?导入初始化文件
import?'./utils/index'
[if !supportLists](3)[endif]调用方法
wx.方法名(参数)
wx.$msg('删除成功')
[if !supportLists]七、[endif]scroll-view
可滚动视图区域。使用竖向滚动时,需要给scroll-view一个固定高度,通过 WXSS 设置 height。组件属性的长度单位默认为px,2.4.0起支持传入单位(rpx/px)。
scroll-x:允许横向滚动。
scroll-y:允许纵向滚动。
?<scroll-view?class="left"?scroll-y>??</scroll-view>
[if !supportLists]八、[endif]wx对象发送ajax请求
[if !supportLists]1、[endif]wx.request() 发送请求
注意:小程序实际使用中,请求的接口必须都是已经配置过的接口??⒔锥危梢灾苯由柚谩安恍Q楹戏ㄓ蛎?,暂不配置。
?wx.request({
??????//?请求接口地址
??????url: 'https://www.bingjs.com:8002/Section/GetSections',
??????//?请求参数
??????data:{},
??????//?请求方式GET/POST
??????method:"GET",
??????//?请求成功后的回调
??????success:({data})=>{
????????resolve(data)
??????},
??????//?请求完成后的回调
??????complete:()=>{
?????????console.log('请求完成');
??????}
????})
[if !supportLists]2、[endif]封装ajax请求方法
(1)定义请求方法
export?let?$request?=?(url,data={},method='GET')=>{
??return?new?Promise((resolve)=>{
????wx.request({
??????url,
??????data,
??????method,
??????success:({data})=>{
????????resolve(data)
??????},
????})
??})
}
(2)定义get请求方法
export?let?$get?=?(url,data={})=>{
??return?$request(url,data,'GET')
}
(3)定义post请求方法
export?let?$post?=?(url,data={})=>{
??return?$request(url,data,'POST')
}
[if !supportLists]九、[endif]格式化时间
[if !supportLists]1、[endif]在后台对数据里的时间戳进行处理
let?data=?await?wx.$get('Subject/GetSubjects',{section_id:id})
data?=?data.map(r=>{
?return?{
??Title:?r.Title,
??Section:?r.Section,
Createtime:?wx.$formatTime(new?Date(parseInt(r.Createtime)))
}
})
[if !supportLists]2、[endif]WXS
WXS(WeiXin Script)是小程序的一套脚本语言,结合 WXML,可以构建出页面的结构。
在wxml页面中,只能在插值{{ }}中写简单的js表达式,而不能调用方法。wxs就是为了能在页面中使用js而存在的。
[if !supportLists](1)[endif]语法
① 变量必须使用var声明,不支持const或者let。
② 不支持箭头函数。
③ 不可以使用模板字符串,字符串连接用+ 。
④ 每一个 .wxs 文件和 <wxs> 标签都是一个单独的模块。每个??槎加凶约憾懒⒌淖饔糜颉?/p>
通过module.exports导出内部的私有变量与函数。
⑤ <wxs> 标签中,module属性值定义标签的模块名;src属性值引入.wxs文件的相对路径。
⑥ 生成date对象使用 getDate(),返回一个当前时间的对象。不使用new Date()。
(2)编写在wxml文件中的 标签内
<wxs?module="tools">
?var?formatTime?=?function(date)?{
????date?=?getDate(parseInt(date))
????var?year?=?date.getFullYear()
????var?month?=?date.getMonth()?+?1
????var?day?=?date.getDate()
????var?hour?=?date.getHours()
????var?minute?=?date.getMinutes()
????var?second?=?date.getSeconds()
????return?[year,?month,?day].map(formatNumber).join('/')?+?'?'?+?[hour,?minute,?second].map(formatNumber).join(':')
}
var?formatNumber?=function(n)?{
???n?=?n.toString()
???return?n[1]???n?:?'0'?+?n
}
module.exports?=?{
???formatTime:formatTime??
}
</wxs>?
<!--?在模板中,对时间数据进行处理?-->
<view>{{tools.formatTime(item.Createtime)}}</view>
(3)编写在wxs文件中,再导入wxml文件
<!--?导入wxs文件?-->
<wxs?module="tools"?src="../../wxs/filter.wxs"></wxs>
<!--?在模板中,对时间数据进行处理?-->
<view>{{tools.formatTime(item.Createtime)}}</view>
十、生命周期函数
1、onLoad 监听页面加载
onLoad函数对页面状态数据的初始化,是生命周期回调—监听页面加载。一 个页面只会调用一次。onLoad函数的参数可以接收打开当前页面所调用的 query参数。
当前页面跳转detail页面后,调用query参数id。
<navigator?url="../detail/detail?id={{item.Id}}"?class="item"?wx:for="{{subjects}}"?wx:key="index">
</navigator>
detail页面中onLoad函数可以获取传递的query参数id。
??onLoad:?function?(options)?{
????//获取题目的id
????let?{id}?=?options
??}
2、onReachBottom 上拉触底
????onReachBottom:function(){
????????this.data.pageIndex++
????????this.getSubjects()
????}
[if !supportLists]3、[endif]onPullDownRefresh 下拉刷新
下拉刷新默认是关闭状态,所以需要先在.json文件中设置允许下拉刷新。
enablePullDownRefresh设置是否开启当前页面下拉刷新。
backgroundColor设置窗口的背景色。
{
??"enablePullDownRefresh":?true,
??"backgroundColor":?"#d1c2d3"
}
下拉刷新动效有默认时间。如果想改变默认的下拉时间,可以用定时器。
wx.stopPullDownRefresh()设置刷新完成后停止下拉刷新动效。
????onPullDownRefresh:function(){
???????setTimeout(()?=>?{
???????????wx.stopPullDownRefresh()
???????},?1000);
????}
十一、简易双向绑定
1、普通属性绑定
在WXML 中,普通的属性的绑定是单向的。如果用户修改了输入框里的值,不会同时改变 this.data.value。
????<input?class="txt"?value="{{title}}"?/>
2、简易双向绑定
如果需要在用户输入的同时改变this.data.value ,需要借助简易双向绑定机制。
通过model:value的方式,将表单里面的数据跟js里面的数据进行了双向绑定。
双向绑定指的是:一处被修改,另一处也一起修改。
???<input?class="txt"?model:value="{{value}}"?/>
3、双向绑定的表达式限制
只能是一个单一字段的绑定;目前,尚不能data 路径。
以下写法都是错误的:
???<input?model:value="值为{{value}}"?/>
???<input?model:value="{{?a?+?b?}}"?/>
???<input?model:value="{{?a.b?}}"?/>
十二、表单组件
1、picker 选择器组件
range:指定一个数组(指定一份展示的数据)。
range-key:如果range数组是一个对象数组,需要添加range-key属性,指定选择器中显示的内容(从对象身上指定一个属性)。
bindchange:value 改变时触发 change 事件,event.detail = {value}。
<picker?class="txt"?bindchange="bindPickerChange"?range-key="Name"?range="{{sections}}">
?????<view>
????????<!--?根据选择器选中的索引,显示对应的名称?-->
????????{{sections[sectionsActiveIndex].Name}}
?????</view>
??</picker>
通过e.detail.value获取当前列表value的索引。
???bindPickerChange:?function(e)?{
console.log(e.detail.value) ?//获取下标
???}
2、input 输入框
placeholder:输入框为空时占位符。
<input?value=""?placeholder="请输入搜索关键字"?/>
3、textarea 多行文本框
maxlength:最大输入长度。设置为 -1 的时候不限制最大长度。
<textarea?maxlength="-1"?value=""?/>
[if !supportLists]六、[endif]js数据更新方法
(1)直接赋值
该方法只更新js中的数据,不会重新渲染到页面。
???this.data.section_id?=?this.data.sections[index].Id
(2)setData()方法
该方法更新数据后,重新渲染页面。
???this.setData({
???????activeIndex:?index
???})