3.2 小程序之WXML 模板(常用)
- 具体详情请查看:微信公众平台-小程序-组件https://developers.weixin.qq.com/miniprogram/dev/component/
view
视图容器
- 相当于
div
<view class="flex-item bc_green">1</view>
- 相当于
scroll-view
可滚动视图区域- 相当于 允许横向滚动,允许纵向滚动
div
,滑块做法
<scroll-view scroll-y bindscrolltoupper="upper" bindscrolltolower="lower" bindscroll="scroll" scroll-into-view="{{toView}}" scroll-top="{{scrollTop}}"> <view id="green" class="scroll-view-item bc_green"></view> <view id="red" class="scroll-view-item bc_red"></view> <view id="yellow" class="scroll-view-item bc_yellow"></view> <view id="blue" class="scroll-view-item bc_blue"></view> </scroll-view>
- 相当于 允许横向滚动,允许纵向滚动
swiper
滑块视图容器- 轮播图组件
<swiper indicator-dots="{{indicatorDots}}" autoplay="{{autoplay}}" interval="{{interval}}" duration="{{duration}}"> <block wx:for="{{imgUrls}}"> <swiper-item> <image src="{{item}}" class="slide-image" width="355" height="150"/> </swiper-item> </block> </swiper>
text
文本
- 相当于
span
<text class="page__title">image</text>
- 相当于
- 表单组件
- button
- checkbox
- form
- input
- label
- picker——普通选择器,时间选择器,日期选择器,默认是普通选择器
- picker-view——嵌入页面的滚动选择器
- radio
- slider——滑动选择器
- switch——开关选择器。
- textarea
- navigator 页面链接。
- 相当于
a
标签,可以跳转页面也可以跳转新的小程序
open-type
跳转方式
navigate
(默认) 保留当前跳转,跳转后可以返回当前页(页面左上角有一个<
可以返回上一页),它与wx.navigateTo跳转效果是一样的;
<navigator url="/page/navigate/navigate?title=navigate">跳转到新页面</navigator>
<navigator target="miniProgram" open-type="navigate" app-id="" path="" extra-data="" version="release">打开绑定的小程序</navigator>
redirect
关闭当前页跳转,是无法返回当前页,它与wx.redirrectTO跳转效果是一样的;
<navigator url="../../redirect/redirect/redirect?title=redirect" open-type="redirect" hover-class="other-navigator-hover">在当前页打开</navigator>
switchTab
跳转底部标签导航指定的页面,它与wx.switchTab跳转效果是一样的;
- 我们可以设置底部和顶部导航,这时候跳转到导航的链接就必须是
switchTab
; <navigator url="/page/index/index" open-type="switchTab" hover-class="other-navigator-hover">切换 Tab</navigator>
- 我们可以设置底部和顶部导航,这时候跳转到导航的链接就必须是
- image 图片。
- 相当于
img
标签
<image style="width: 200px; height: 200px; background-color: #eeeeee;" mode="{{item.mode}}" src="{{src}}"></image>
- 相当于
3.3 小程序之WXSS 样式
- 单位:一般我们做WEB前端页面都是都是使用px(像素)做单位的,那么做小程序怎么办呢?
- 小程序的设计稿的宽都是750px,也就是市场上面流行的ip6,7,8的大小,WXSS 在底层支持新的尺寸单位 rpx, ;
- rpx(responsive pixel): 可以根据屏幕宽度进行自适应。规定屏幕宽为750rpx。
- 所以换算比例为1:1,例如设计稿上是66px的高,那么小程序上面设置的高则是:66rpx;
3.4 小程序之WXML 模板 进阶
简单绑定
- 数据绑定使用 Mustache 语法(双大括号)将变量包起来,可以作用于:
- 内容
<!-- index.wxml --> <view> {{ message }} </view>
//index.js Page({ data: { message: 'Hello MINA!' } })
- 组件属性(需要在双引号之内)
<!-- index.wxml --> <view id="item-{{id}}"> </view>
//index.js Page({ data: { id: 0 } })
总结: 我们在.js里面的page()-data定义对象,例 "id:0",就可以在页面上{{id}},输出0, 还可以在后面的js代码中绑定事件,动态改变 data定义对象 的值,页面的值就相应改变了; WEB的js代码需要找到元素,找到值,再给元素赋值,比较麻烦; 而小程序的js就一开始绑定了变量,然后再js里面改变变量,然后页面就可以相应改变了,省去了找元素这一步骤。
列表渲染 - wx:for
- 在组件上使用 wx:for 控制属性绑定一个数组,即可使用数组中各项的数据重复渲染该组件。
- 默认数组的当前项的下标变量名默认为 index,数组当前项的变量名默认为 item
<!-- index.wxml --> <view wx:for="{{array}}"> {{index}}: {{item.message}} </view>
//index.js Page({ data: { array: [{ message: 'foo', }, { message: 'bar' }] } })
- 使用 wx:for-item 可以指定数组当前元素的变量名,使用 wx:for-index 可以指定数组当前下标的变量名:
<!-- index.wxml --> <view wx:for="{{array}}" wx:for-index="idx" wx:for-item="itemName"> {{idx}}: {{itemName.message}} </view>
wx:for 也可以嵌套,下边是一个九九乘法表
<!-- index.wxml --> <view wx:for="{{[1, 2, 3, 4, 5, 6, 7, 8, 9]}}" wx:for-item="i"> <view wx:for="{{[1, 2, 3, 4, 5, 6, 7, 8, 9]}}" wx:for-item="j"> <view wx:if="{{i <= j}}"> {{i}} * {{j}} = {{i * j}} </view> </view> </view>
- block wx:for (注意:
<block/>
并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性。) - 类似 block wx:if,也可以将 wx:for 用在标签上,以渲染一个包含多节点的结构块。例如:
<!-- index.wxml --> <block wx:for="{{[1, 2, 3]}}"> <view> {{index}}: </view> <view> {{item}} </view> </block>
总结: wx:for 列表渲染 相当于PHP的foreach循环,大同小异 php: foreach($data => $key => $value){ echo $key.'=>'.$value; } ThinkPHP 3.2 <volist name="data" id="value"> {$key}:{$value} </volist> ThinkPHP 5 {volist name="data" id="value"} {$key}:{$value} {/volist} 小程序: <view wx:for="{{data}}" wx:for-index="key" wx:for-item="value"> {{key}}: {{value}} </view>
条件渲染 - wx:if
- 在框架中,使用 wx:if=”{{condition}}” 来判断是否需要渲染该代码块:
<view wx:if="{{condition}}"> True </view>
也可以用 wx:elif 和 wx:else 来添加一个 else 块:
<view wx:if="{{length > 5}}"> 1 </view> <view wx:elif="{{length > 2}}"> 2 </view> <view wx:else> 3 </view>
block wx:if
因为 wx:if 是一个控制属性,需要将它添加到一个标签上。如果要一次性判断多个组件标签,可以使用一个
<block/>
标签将多个组件包装起来,并在上边使用 wx:if 控制属性。<block wx:if="{{true}}"> <view> view1 </view> <view> view2 </view> </block>
注意:
<block/>
并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性。
模板
- WXML提供模板(template),可以在模板中定义代码片段,然后在不同的地方调用。
- 定义模板
- 使用 name 属性,作为模板的名字。然后在内定义代码片段,如:
<!-- index: int msg: string time: string --> <template name="msgItem"> <view> <text> {{index}}: {{msg}} </text> <text> Time: {{time}} </text> </view> </template>
使用模板
- 使用 is 属性,声明需要的使用的模板,然后将模板所需要的 data 传入,如:
<template is="msgItem" data="{{...item}}"/>
Page({ data: { item: { index: 0, msg: 'this is a template', time: '2016-09-15' } } })
- is 属性可以使用 Mustache 语法,来动态决定具体需要渲染哪个模板:
<template name="odd"> <view> odd </view> </template> <template name="even"> <view> even </view> </template>
<block wx:for="{{[1, 2, 3, 4, 5]}}"> <template is="{{item % 2 == 0 ? 'even' : 'odd'}}"/> </block>
- 模板的作用域
- 模板拥有自己的作用域,只能使用 data 传入的数据以及模版定义文件中定义的 模块。
- 使用 is 属性,声明需要的使用的模板,然后将模板所需要的 data 传入,如:
事件
什么是事件
- 事件是视图层到逻辑层的通讯方式。
- 事件可以将用户的行为反馈到逻辑层进行处理。
- 事件可以绑定在组件上,当达到触发事件,就会执行逻辑层中对应的事件处理函数。
- 事件对象可以携带额外信息,如 id, dataset, touches。
事件的使用方式
- 点击事件
bindtap="tapName"
,在标签上面绑定事件
<view id="tapTest" data-hi="WeChat" bindtap="tapName"> Click me! </view>
Page({ //点击 上面的 view 即可触发 tapName 函数 tapName: function(event) { console.log(event) } })
- 点击事件
3.6 引用
- WXML 提供两种文件引用方式import和include。
import
- import可以在该文件中使用目标文件定义的template,如:
- 在 item.wxml 中定义了一个叫item的template:
<!-- item.wxml --> <template name="item"> <text>{{text}}</text> </template>
- 在 index.wxml 中引用了 item.wxml,就可以使用item模板:
<import src="item.wxml"/> <template is="item" data="{{text: 'forbar'}}"/>
include
- include 可以将目标文件除了 外的整个代码引入,相当于是拷贝到 include 位置,如:
<!-- index.wxml --> <include src="header.wxml"/> <view> body </view> <include src="footer.wxml"/>
<!-- header.wxml --> <view> header </view>
<!-- footer.wxml --> <view> footer </view>
3.5 WXS
- WXS(WeiXin Script)是小程序的一套脚本语言,结合 WXML,可以构建出页面的结构。
- WXS开发手册:https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxs/
- 注意(来自官方文档)
- wxs 不依赖于运行时的基础库版本,可以在所有版本的小程序中运行。
- wxs 与 javascript 是不同的语言,有自己的语法,并不和 javascript 一致。
- wxs 的运行环境和其他 javascript 代码是隔离的,wxs 中不能调用其他 javascript 文件中定义的函数,也不能调用小程序提供的API。
- wxs 函数不能作为组件的事件回调。
- 由于运行环境的差异,在 iOS 设备上小程序内的 wxs 会比 javascript 代码快 2 ~ 20 倍。在 android 设备上二者运行效率无差异。
- 和js差不多,一般开发过程中都是使用.js写逻辑
- 在开发微信小程序的时候,应该根据情况,选择使用js或wxs。
- wxs是专门用于wxml页面的。
- wxs和js不能互相直接调用。
- 有的事情,用wxs和js都能实现,但是你会发现用wxs更方便、直接。
- 案例链接:https://www.jianshu.com/p/097d47a83d5e
3.5 常用API
- 框架提供丰富的微信原生API,可以方便的调起微信提供的能力,如获取用户信息,本地存储,支付功能等。
- 说明:
- wx.on 开头的 API 是监听某个事件发生的API接口,接受一个 CALLBACK 函数作为参数。当该事件触发时,会调用 CALLBACK 函数。
- 如未特殊约定,其他 API 接口都接受一个OBJECT作为参数。
- OBJECT中可以指定success
接口调用成功的回调函数
, fail接口调用失败的回调函数
, complete接口调用结束的回调函数(调用成功、失败都会执行)
来接收接口调用结果。
3.5.0 小程序的生命周期-页面加载顺序
小程序的生命周期——App.js
- App() 必须在 app.js 中注册,且不能注册多个。所以App()方法在一个小程序中有且仅有一个。
App() 函数用来注册一个小程序。接受一个 object 参数,其指定小程序的生命周期函数等。先上代码:
App({ onLaunch: function () { console.log('App onLaunch'); //当小程序初始化完成时,会触发 onLaunch(全局只触发一次)。 }, onShow:function (){ console.log('App onShow'); //当小程序启动,或从后台进入前台显示,会触发 onShow }, onHide:function(){ console.log('App onHide'); //当小程序从前台进入后台,会触发 onHide }, onError:function(){ console.log('App onError'); 小程序发生脚本错误,或者 api 调用失败时,会触发 onError 并带上错误信息 } });
总结:将原有的app.js中替换为上面的代码,首次打开小程序,可以在Log信息中看到以下Log信息,会看到onShow()方法会执行两次
App onLaunch App onShow() App onShow()
页面的生命周期
- Page() 函数用来注册一个页面。接受一个 object 参数,其指定页面的初始数据、生命周期函数、事件处理函数等。
- 生命周期函数
onLoad: 页面加载 * 一个页面只会调用一次。 * 接收页面参数 可以获取wx.navigateTo和wx.redirectTo及<navigator/>中的 query。 onShow: 页面显示 * 每次打开页面都会调用一次。 onReady: 页面初次渲染完成 * 一个页面只会调用一次,代表页面已经准备妥当,可以和视图层进行交互。 onHide: 页面隐藏 当navigateTo或底部tab切换时调用。 onUnload: 页面卸载 当redirectTo或navigateBack的时候调用。
- 总结
在app.js里面的 onLaunch 写整个项目都会调用到的逻辑以及一些初始化操作,例如,小程序背景音乐的播放控制等;
在页面的.js文件 调用 onLoad 接收参数,调用接口,获取数据,更新渲染页面;
每次打开页面,都会触发 onShow ,所以做购物车的时候,购物车信息要经常更新,就可以在页面的.js文件 调用 onShow 查询购物车,并显示;
3.5.1 wx.request 发起网络请求
-相当于AJAX、相当于接口开发。
- 例:
wx.request({
url: 'https://api.001php.com/api?url=page_class',//开发者服务器接口地址
method: 'POST',//默认:GET,(需大写)有效值:OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT
dataType: 'json',//json, 如果设为json,会尝试对返回的数据做一次 JSON.parse
data: {id:1},//请求的参数
header: {
"Content-Type": "application/x-www-form-urlencoded" //设置请求的 header,header 中不能设置 Referer。
},
//成功后的回调
success: function (res) {
// console.log(res.data) //打印返回数据
//把返回数据存为 data 变量,直接可以在页面上显示输出
that.setData({
list: res.data
})
}
})
//注:header使用什么"Content-Type"?
//application/x-www-form-urlencoded : 通过页面表单方式提交
//application/json : json(要反序列化成字符串),php不能直接解析json字符串
//所以我们做小程序接口,都有重新设置 header Content-Type 为: application/x-www-form-urlencoded
3.5.2 界面-交互反馈-弹出提示框
显示消息提示框:wx.showToast(OBJECT)
- 示例代码:
wx.showToast({ title: '登陆成功',//提示的内容 icon: 'success',//图标,有效值 "success", "loading", "none" duration: 2000,//提示的延迟时间,单位毫秒,默认:1500 mask:true,// 是否显示透明蒙层,防止触摸穿透,默认:false success:function(res){ //接口调用成功的回调函数 wx.hideToast()//隐藏消息提示框 } })
- 示例代码:
- 隐藏消息提示框:wx.hideToast()
- 一般是显示提示框接口调用成功的时候隐藏
显示 loading 提示框:wx.showLoading(OBJECT),需主动调用 wx.hideLoading 才能关闭提示框
- 示例代码:
wx.showLoading({ title: '请选择地址',//提示的内容 mask:true,// 是否显示透明蒙层,防止触摸穿透,默认:false success:function(res){ //接口调用成功的回调函数 } })
- 示例代码:
- 隐藏 loading 提示框 - wx.hideLoading()
- 一般是发起网络请求接口的时候调用
显示 loading 提示框
,再在网络请求完成后,调用,wx.hideLoading()
,隐藏loading
- 一般是发起网络请求接口的时候调用
显示模态弹窗:wx.showModal(OBJECT)
- 示例代码:
wx.showModal({ title: '删除图片', content: '确定要删除该图片?', showCancel: true,//是否显示取消按钮 cancelText:"否",//默认是“取消” cancelColor:'skyblue',//取消文字的颜色 confirmText:"是",//默认是“确定” confirmColor: 'skyblue',//确定文字的颜色 success: function (res) { if (res.cancel) { //点击取消,默认隐藏弹框 } else { //点击确定 temp.splice(index, 1), that.setData({ tempFilePaths: temp, }) } }, fail: function (res) { },//接口调用失败的回调函数 complete: function (res) { },//接口调用结束的回调函数(调用成功、失败都会执行) })
- 示例代码:
3.5.3 导航-跳转页面
- wx.navigateTo(OBJECT)
- 保留当前页面,跳转到应用内的某个页面,使用wx.navigateBack可以返回到原页面。
- 示例代码:
wx.navigateTo({
url: 'test?id=1'
})
wx.redirectTo(OBJECT)
关闭当前页面,跳转到应用内的某个页面。
示例代码:
wx.redirectTo({ url: 'test?id=1' })
wx.reLaunch(OBJECT)
- 关闭所有页面,打开到应用内的某个页面。
- 示例代码:
wx.reLaunch({ url: 'test?id=1' }) wx.switchTab(OBJECT) 跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面 wx.switchTab({ url: '/index' })
wx.navigateBack(OBJECT)
- 关闭当前页面,返回上一页面或多级页面。可通过 getCurrentPages()) 获取当前的页面栈,决定需要返回几层。
- 示例代码:
// 注意:调用 navigateTo 跳转时,调用该方法的页面会被加入堆栈,而 redirectTo 方法则不会。见下方示例代码 // 此处是A页面 wx.navigateTo({ url: 'B?id=1' }) // 此处是B页面 wx.navigateTo({ url: 'C?id=1' }) // 在C页面内 navigateBack,将返回A页面 wx.navigateBack({ delta: 2 }) // 如果是在C页面内 navigateBack,将返回B页面 wx.navigateBack()
Tip
- tip: wx.navigateTo 和 wx.redirectTo 不允许跳转到 tabbar 页面,只能用 wx.switchTab 跳转到 tabbar 页面
3.5.4 缓存
- 关于本地缓存
1.wx.setStorage(wx.setStorageSync)、wx.getStorage(wx.getStorageSync)、wx.clearStorage(wx.clearStorageSync)可以对本地缓存进行设置、获取和清理。本地缓存最大为10MB
2.localStorage 是永久存储 一、异步缓存
设置异步缓存:wx.setStorage(OBJECT)
- 将数据存储在本地缓存中指定的 key 中,会覆盖掉原来该 key 对应的内容
wx.setStorage({ key:"key", data:"value" })
获取异步缓存:wx.getStorage(OBJECT)
- 从本地缓存中异步获取指定 key 对应的内容。
wx.getStorage({ key: 'key', success: function(res) { console.log(res.data) } })
wx.getStorageInfo(OBJECT)
- 异步获取当前storage的相关信息
wx.getStorageInfo({ success: function(res) { console.log(res.keys) console.log(res.currentSize) console.log(res.limitSize) } })
wx.removeStorage(OBJECT)
- 从本地缓存中异步移除指定 key 。
wx.removeStorage({ key: 'key', success: function(res) { console.log(res.data) } })
- 二、同步缓存
- 设置同步缓存:wx.setStorageSync(KEY,DATA)
- 将 data 存储在本地缓存中指定的 key 中,会覆盖掉原来该 key 对应的内容,这是一个同步接口。
- 获取同步缓存:wx.getStorageSync(KEY)
- 从本地缓存中同步获取指定 key 对应的内容。
- wx.getStorageInfoSync
- 同步获取当前storage的相关信息
- wx.removeStorageSync(KEY)
- 从本地缓存中同步移除指定 key 。
- 设置同步缓存:wx.setStorageSync(KEY,DATA)
- 三、清理缓存
- wx.clearStorage():清理本地数据缓存。
- wx.clearStorageSync():同步清理本地数据缓存
- 四、关于同步缓存和异步缓存的区别
- 以Sync(同步,同时)结尾的都是都是同步缓存,二者的区别是,异步不会阻塞当前任务,同步缓存直到同步方法处理完才能继续往下执行。
- 但是一般情况下不要用清除所有的缓存,如果想要清除相应的缓存,设置对应的缓存内容为空数组就好