微信小程序基础
一、页面文件
小程序中的页面文件分为四个,index.wxml、index.wxss、index.js和 index.json
index.wxml 是布局文件,index.wxss 是样式文件,index.js 是逻辑文件, index.json 是配置文件
页面级别的配置会覆盖全局级别的配置
小程序全局通用配置文件只有 app.wxss、app.js和app.json文件,app.wxml文件没有
小程序页面级别配置文件有index.js、index.json、index.wxml和index.wxss文件
微信小程序的分层,配置层(.json),视图层(.wxml、.wxss),逻辑层(.js)
二、tabBar 组件
tabBar 组件必须配置 list,数量最少为两个,最多为五个,list 为数组
list 是 配置 pagePath 和 text,pagePath 为页面路径,text为 tab 上按钮文字,iconPath 为默认图片路径,selectedIconPath 为选中图片路径
当 position 为 top 时,不显示 icon,不显示 iconPath 和 selectedIconPath
position 默认为 bottom,在底部的
color 为 tabBar 的默认颜色,selectedColor 为 tabBar 的选中颜色
示例代码如下:
"tabBar":{
"backgroundColor": "#030",
"position": "top",
"color": "#ccc",
"selectedColor": "#f00",
"list": [
{
"selectedIconPath": "",
"iconPath": "",
"pagePath": "pages/test/test",
"text": "首页"
},
{
"selectedIconPath": "",
"iconPath": "",
"pagePath": "pages/logs/logs",
"text": "日志"
}
]
}
三、小程序框架 MINA
基于 react native 的响应式开发框架,组件化开发,数据驱动
分为视图层和逻辑层,数据变化,逻辑也会变化
数据绑定,通过插值表达式,{{}}
条件渲染,wx:if、wx:elif、wx:else
列表渲染,wx:for,遍历时需要加 wx:key,如果需要修改名字,双层循环中里面的循环获取到外面的循环,如修改 item则为wx:for-item=“user”,
修改 index则为 wx:for-index=“idx”
示例代码
test.js
data: {
"msg": 'hello word',
"list": [
"vue",
"react",
"node"
],
"show": true,
"list2": [
{name: "张三", city: "上海", course: ["vue", "react", "node"]},
{ name: "李四", city: "北京", course: ["vue", "react", "node"]},
{ name: "王五", city: "深圳", course: ["vue", "react", "node"]}
]
},
test.wxml
<!--pages/test/test.wxml-->
<text wx:if="{{ show }}">
{{ msg }}
{{ list }}
</text>
<view wx:for="{{ list }}" wx:key="{{ index}}">
{{ item }} {{ index }}
</view>
<view wx:for="{{ list2 }}" wx:key="{{index}}" wx:for-item="user" wx:for-index="{{idx}}">
{{user.name}} {{ user.city}} {{ idx }}
<view wx:for="{{ user.course }}" wx:key="{{ index }}">
{{ item}} {{ index }}
</view>
</view>
四、小程序的页面配置
-
data 是页面第一次渲染使用的初始数据。页面加载时,data 将会以JSON 字符串的形式由逻辑层传至渲染层,因此 data 中的数据必须是可以转成 JSON 的类型:字符串,数字,布尔值,对象,数组。
生命周期函数 -
onLoad(Object query) 页面加载时触发,只调用一次
-
onShow() 页面显示/切入前台时触发
-
onReady() 页面初次渲染完成时触发,一个页面只会调用一次,代表页面已经准备妥当,可以和视图层进行交互
-
onHide() 页面隐藏/切入后台时触发
-
onUnload() 页面卸载时触发
页面事件处理函数
-
onPullDownRefresh() 监听用户下拉刷新事件
-
onReachBottom() 监听用户上拉触底事件
-
onPageScroll(Object object) 监听用户滑动页面事件
-
onShareAppMessage(Object object) 监听用户点击页面内转发按钮(button 组件 open-type=“share”)或右上角菜单“转发”按钮的行为,并自定义转发内容
-
onResize(Object object) 小程序屏幕旋转时触发
-
onTabItemTap(Object object) 点击 tab 时触发
五、小程序的全局配置
小程序的全局配置分为
pages 页面路径列表、window 全局的默认窗口表现、tabBar 底部 tab 栏的表现、networkTimeout 网络超时时间和debug开启debug 模式等等很多
小程序的全局配置在 app.json文件中
示例代码 app.json
{
"pages": [
"pages/index/index",
"pages/logs/logs"
],
"window": {
"backgroundTextStyle": "dark",
"navigationBarBackgroundColor": "#0f0",
"navigationBarTitleText": "Dell",
"navigationBarTextStyle": "white",
"backgroundColor": "pink",
"enablePullDownRefresh": true
},
"tabBar": {
"color": "purple",
"selectedColor": "red",
"position": "bottom",
"list": [
{
"pagePath": "pages/index/index",
"text": "首页",
"iconPath": "resources/buy.png",
"selectedIconPath": "resources/sell.png"
},
{
"pagePath": "pages/logs/logs",
"text": "日志",
"iconPath": "resources/buy.png",
"selectedIconPath": "resources/sell.png"
}
]
},
"networkTimeout": {
"request": 10000,
"downloadFile": 10000
},
"debug": false,
"style": "v2",
"sitemapLocation": "sitemap.json"
}
六、小程序的逻辑层
app.js
//app.js
App({
onLaunch: function () {
// 展示本地存储能力
var logs = wx.getStorageSync('logs') || []
logs.unshift(Date.now())
wx.setStorageSync('logs', logs)
// 登录
wx.login({
success: res => {
// 发送 res.code 到后台换取 openId, sessionKey, unionId
}
})
// 获取用户信息
wx.getSetting({
success: res => {
if (res.authSetting['scope.userInfo']) {
// 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框
wx.getUserInfo({
success: res => {
// 可以将 res 发送给后台解码出 unionId
this.globalData.userInfo = res.userInfo
// 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
// 所以此处加入 callback 以防止这种情况
if (this.userInfoReadyCallback) {
this.userInfoReadyCallback(res)
}
}
})
}
}
})
},
globalData: {
userInfo: null
}
})
index.js
//index.js
//获取应用实例
const app = getApp()
Page({
data: {
motto: 'Hello World',
userInfo: {},
hasUserInfo: false,
canIUse: wx.canIUse('button.open-type.getUserInfo')
},
//事件处理函数
bindViewTap: function() {
wx.navigateTo({
url: '../logs/logs'
})
},
onLoad: function () {
if (app.globalData.userInfo) {
this.setData({
userInfo: app.globalData.userInfo,
hasUserInfo: true
})
} else if (this.data.canIUse){
// 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
// 所以此处加入 callback 以防止这种情况
app.userInfoReadyCallback = res => {
this.setData({
userInfo: res.userInfo,
hasUserInfo: true
})
}
} else {
// 在没有 open-type=getUserInfo 版本的兼容处理
wx.getUserInfo({
success: res => {
app.globalData.userInfo = res.userInfo
this.setData({
userInfo: res.userInfo,
hasUserInfo: true
})
}
})
}
},
getUserInfo: function(e) {
console.log(e)
app.globalData.userInfo = e.detail.userInfo
this.setData({
userInfo: e.detail.userInfo,
hasUserInfo: true
})
}
})
logs.js
//logs.js
const util = require('../../utils/util.js')
Page({
data: {
logs: []
},
onLoad: function () {
this.setData({
logs: (wx.getStorageSync('logs') || []).map(log => {
return util.formatTime(new Date(log))
})
})
}
})
index.wxml
<view class="userinfo">
<button wx:if="{{!hasUserInfo && canIUse}}" open-type="getUserInfo" bindgetuserinfo="getUserInfo"> 获取头像昵称 </button>
<block wx:else>
<image bindtap="bindViewTap" class="userinfo-avatar" src="{{userInfo.avatarUrl}}" mode="cover"></image>
<text class="userinfo-nickname">{{userInfo.nickName}}</text>
</block>
</view>
<view class="usermotto">
<text class="user-motto">{{motto}}</text>
</view>