四、微信小程序框架
微信小程序开发框架的目标是通过尽可能简单、高效的方式让开发者可以在微信中开发具有原生APP体验的服务。框架提供了自己的视图层描述语言WXML和WXSS,以及基于JavaScript的逻辑层框架,并在视图层与逻辑层间提供了数据传输和事件系统,可以让开发者可以方便的聚焦于数据与逻辑上。
(1)框架全局配置 Pages、Window、TabBar
官方文档
全局配置:app.json
{
// 基础页面配置
"pages": [
"pages/farm/index",
"pages/comp/index",
"pages/api/index",
"pages/other/index"
],
// 分包页面配置
"subpackages": [
{
"root": "comp",
"pages": [
"scroll-view/index"
]
}
],
// 页面配置规则
"preloadRule": {
"pages/farm/index": {
"network": "all",
"packages": [
"farm"
]
}
},
// 默认启动路径
"entryPagePath": "pages/farm/index",
// 全局默认窗口表现(可以被页面表现覆盖)
"window": {
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#f1f1f1",
"navigationBarTitleText": "微信小程序",
"navigationBarTextStyle": "black"
},
// 底部导航栏目配置
"tabBar": {
"color": "#000",
"selectedColor": "#0050FF",
"list": [
{
"iconPath": "/static/tabbar-icons/store.png",
"selectedIconPath": "/static/tabbar-icons/store_s.png",
"text": "框架",
"pagePath": "pages/farm/index"
},
{
"iconPath": "/static/tabbar-icons/home.png",
"selectedIconPath": "/static/tabbar-icons/home_s.png",
"text": "组件",
"pagePath": "pages/comp/index"
},
{
"iconPath": "/static/tabbar-icons/sns.png",
"selectedIconPath": "/static/tabbar-icons/sns_s.png",
"text": "API",
"pagePath": "pages/api/index"
},
{
"iconPath": "/static/tabbar-icons/user.png",
"selectedIconPath": "/static/tabbar-icons/user_s.png",
"text": "其他",
"pagePath": "pages/other/index"
}
]
},
// 小程序接口权限配置
"permission": {
"scope.userLocation": {
"desc": "你的位置信息将用于小程序位置接口的效果展示"
}
},
// weui 组件库相关配置
"style": "v2",
"useExtendedLib": {
"weui": true
},
// 网络超时时间配置
"networkTimeout": {
"request": 10000,
"downloadFile": 10000
},
// 是否开启调试模式
"debug": true,
// 指明 sitemap 配置文件位置
"sitemapLocation": "sitemap.json"
}
(2)框架单页面配置
官方文档
具体页面配置:xxx.json
{
//
"usingComponents": {
"mp-cells": "weui-miniprogram/cells/cells",
"mp-cell": "weui-miniprogram/cell/cell",
"mp-icon": "weui-miniprogram/icon/icon"
},
//
"navigationBarBackgroundColor": "#007cba",
//
"navigationBarTextStyle": "white",
//
"navigationBarTitleText": "裤架相关功能及演示",
//
"backgroundColor": "#eeeeee",
//
"backgroundTextStyle": "light"
}
(3)框架接口
注册小程序 app.js 文件,配置全局变量 GlobalData ,可以随时在页面中读取和存储数据,比Storage方便很多
// 设置
App({
globalData: {
userName: 'buhe'
},
onLaunch (options) {
},
onShow (options) {
},
onHide () {
},
onError (msg) {
console.log(msg)
}
})
// 调用
const app = getApp()
app.globalData.userName = 'newName'
注册小程序中的一个页面 Page ,接受一个
Object
类型参数,其指定页面的初始数据、生命周期回调、事件处理函数等。
Page({
data: {
text: "This is page data."
},
onLoad: function(options) {
// Do some initialize when page load.
},
onShow: function() {
// Do something when page show.
},
onReady: function() {
// Do something when page ready.
},
onHide: function() {
// Do something when page hide.
},
onUnload: function() {
// Do something when page close.
},
onPullDownRefresh: function() {
// Do something when pull down.
},
onReachBottom: function() {
// Do something when page reach bottom.
},
onShareAppMessage: function () {
// return custom share data when user share.
},
onPageScroll: function() {
// Do something when page scroll
},
onResize: function() {
// Do something when page resize
},
onTabItemTap(item) {
console.log(item.index)
console.log(item.pagePath)
console.log(item.text)
},
// 事件函数,可以当做事件来进行调用
viewTap: function() {
this.setData({
text: 'Set some data for updating view.'
}, function() {
// this is setData callback
})
},
// 开发者可以添加任意的函数或数据到 Object 参数中,在页面的函数中用 this 可以访问
customData: {
hi: 'MINA'
}
})
(4)框架 WXML 语法 - ToDoList
<view>
<view class="title">
{
{ title }}
</view>
<view class="btns">
<button class="btn" bindtap="isHunger">好的</button>
<button class="btn" bindtap="noHunger">不饿</button>
</view>
<view class="title" wx:if="{
{hungerTag}}">
<view wx:for="{
{foodsList}}" wx:for-index="idx" wx:for-item="food" wx:key="idx">
{
{ food }}
</view>
</view>
</view>
.title{
margin: 40rpx 0;
text-align: center;
}
.btn{
margin: 20rpx;
}
// farm/todo-list/index.js
Page({
/**
* 页面的初始数据
*/
data: {
hungerTag: false,
title:'吃点什么吧?',
foodsList:[ '西蓝花', '玫瑰花', '喇叭花', '牵牛花', '小翠花']
},
isHunger(){
this.setData({
hungerTag: true
})
},
noHunger(){
this.setData({
hungerTag: false
})
}
})
(5)框架事件绑定
- 什么是小程序事件绑定?
事件就是用户的一些操作行为,如长按,点击,拖动,触摸屏幕等,都是事件。专业的讲,如下:
- 事件是视图层到逻辑层的通讯方式。
- 事件可以将用户的行为反馈到逻辑层进行处理。
- 事件可以绑定在组件上,当组件触发事件,就会执行逻辑层中对应的事件处理函数。
- 事件分为:冒泡事件 和 非冒泡事件,
bind
事件绑定不会阻止冒泡事件向上冒泡,catch
事件绑定可以阻止冒泡事件向上冒泡- 事件对象可以携带额外信息,如id, dataset, touches。
- 小程序事件都有哪些?
- 点击事件 tap
- 长按事件 longtap
- 触摸事件 touchstart ,touchend,touchmove,touchcancel
- 其他事件,如:submit,input…
- 小程序事件绑定如何传递参数?
属性 类型 说明 type String 事件类型 timeStamp Integer 事件生成时的时间戳 target Object 触发事件的组件的一些属性值集合 currentTarget Object 当前组件的一些属性值集合
在组件中可以定义数据,这些数据将会通过事件传递给 SERVICE。书写方式:以data-
开头,多个单词由连字符-
链接,不能有大写(大写会自动转成小写)如data-element-type
,最终在 event.target.dataset 中会将连字符转成驼峰elementType
。
<button
data-alpha-beta="1"
data-alphaBeta="2"
bindtap="bindViewTap"
style="margin-top:40rpx;"> 点击事件测试 </button>
<view class="info">
事件类型是:{
{eventTag.type}}
</view>
<view class="info">
传递参数 alphaBeta :{
{eventTag.target.dataset.alphaBeta}}
</view>
<view class="info">
传递参数 alphabeta :{
{eventTag.target.dataset.alphabeta}}
</view>
Page({
data:{
eventTag:{
}
},
bindViewTap:function(event){
this.setData({
eventTag: event
})
console.log(event)
event.target.dataset.alphaBeta === 1 // - 会转为驼峰写法
event.target.dataset.alphabeta === 2 // 大写会转为小写
}
})
(6)框架自定义组件
父组件相关代码
<!--farm/ucomp/index.wxml-->
<view style="margin:30rpx 30rpx;">
当前页面引入了自定义组件 : mfooter
</view>
<view style="margin:30rpx 30rpx;">
通信数据 : {
{showInfo}}
</view>
<view style="margin:30rpx 30rpx;background:#007cba;color:#fff;padding:20rpx;">组件第一次调用</view>
<mfooter num="888" min="8" bind:footerEvent="childTruggerEventA"/>
<view style="margin:30rpx 30rpx;background:#007cba;color:#fff;padding:20rpx;">组件第二次调用</view>
<mfooter num="999" min="9" bind:footerEvent="childTruggerEventB"/>
data: {
showInfo:'初始化父组件显示信息'
},
childTruggerEventA(event){
console.log("888 的组件触发了父组件的事件")
console.log("接收到组件的数据是:"+event.detail)
this.setData({
showInfo:"接收到组件的数据是:"+event.detail
})
},
childTruggerEventB(event){
console.log("999 的组件触发了父组件的事件")
console.log("接收到组件的数据是:"+event.detail)
this.setData({
showInfo:"接收到组件的数据是:"+event.detail
})
}
{
"usingComponents": {
"mfooter": "/components/mfooter/index"
}
}
子组件相关代码
<view style="margin:30rpx 30rpx;" bindtap="callParentInfoChange">
传递过来的 num 参数是: {
{ num }}
</view>
<view style="margin:30rpx 30rpx;" bindtap="callParentInfoChange">
传递过来的 min 参数是: {
{ min }}
</view>
<view class="header">
学而时习之,不亦说乎!
</view>
// components/header/index.js
Component({
/**
* 组件的属性列表
*/
properties: {
num: Number,
min: {
type: Number,
value: 0,
observer: function (newVal, oldVal) {
// 属性值变化时执行 可省略
}
}
},
/**
* 组件的初始数据
*/
data: {
name:"蜡笔小新"
},
/**
* 组件的方法列表
*/
methods: {
callParentInfoChange(){
console.log(this.data.min)
this.triggerEvent('footerEvent', this.data.min) //myevent自定义名称事件,父组件中使用
}
}
})
{
"component": true,
"usingComponents": {
}
}
/* components/header/index.wxss */
.header{
position: fixed;
bottom: 0;
left: 0;
width: 100%;
height: 70rpx;
line-height: 70rpx;
text-align: center;
background-color: #007cba;
color: #fff;
}
(7)wxs 语法体验及使用
// 文件模式声明
var getMax = function (arr){
var max = arr[0]
for(var i=1;i<arr.length;i++){
max = max > arr[i] ? max : arr[i]
}
return max
}
module.exports = {
getMax: getMax
};
// 页面初始化数据
data: {
numArr:[
32,
12,
45,
65,
78,
56,
98,
66
]
},
// wxml 中直接声明及调用
<wxs src="./tools.wxs" module="tools" />
<view> 最大的值是:{
{
tools.getMax(numArr)}} </view>
<wxs module="otools">
var getMin = function (arr){
var min = arr[0]
for(var i=1;i<arr.length;i++){
min = min > arr[i] ? arr[i] : min
}
return min
}
module.exports.getMin = getMin;
</wxs>
<view> 最小的值是:{
{
otools.getMin(numArr)}} </view>