微信小程序知识点总结:
小程序的代码结构与vue的代码结构相近,所以我们在构建微信小程序的时候尽可能的去将一些公共的方法单独用js进行封装.
1:微信小程序 App.js 是入口的js也是全局的js
//app.js
var util = require('./utils/util.js');
var api = require('/pages/config/api.js');
var user = require('./utils/use.js');
App({
onLaunch: function (options) {
// 展示本地存储能力
const updateManager = wx.getUpdateManager();
wx.getUpdateManager().onUpdateReady(function () {
wx.showModal({
title: '更新提示',
content: '新版本已经准备好,是否重启应用?',
success: function (res) {
if (res.confirm) {
// 新的版本已经下载好,调用 applyUpdate 应用新版本并重启
updateManager.applyUpdate()
}
}
})
})
},
onShow: function (options) {
user.checkLogin().then(res => {
this.globalData.hasLogin = true;
}).catch(() => {
this.globalData.hasLogin = false;
});
},
globalData: {
hasLogin: false,
share: false, // 分享默认为false
//获取设备顶部窗口的高度(不同设备窗口高度不一样,根据这个来设置自定义导航栏的高度)
//这个最初我是在组件中获取,但是出现了一个问题,当第一次进入小程序时导航栏会把
//页面内容盖住一部分,当打开调试重新进入时就没有问题,这个问题弄得我是莫名其妙
//虽然最后解决了,但是花费了不少时间
statusBarHeight: wx.getSystemInfoSync()['statusBarHeight']
}
})
可以根据 wx.getSystemInfoSync来获取设备窗口的高度如下图
2: 微信小程序 公共js的封装
我们在构建项目的时候有很多可以复用的方法.比如:请求方法/验证方法/登录方法/放置缓存的方法
在写之前我们了解一下微信小程序
Promise ,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息
对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是Promise这个名字的由来,它的英语意思就是“承诺”,表示其他手段无法改变。
用法:
ES6 规定,Promise对象是一个构造函数,用来生成Promise实例。
下面代码创造了一个Promise实例。
const promise = new Promise(function(resolve, reject) {
// ... some code
if (/* 异步操作成功 */){
resolve(value);
} else {
reject(error);
}
});
Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject。它们是两个函数,由 JavaScript 引擎提供,不用自己部署。
resolve函数的作用是,将Promise对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;reject函数的作用是,将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。
Promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数。
promise.then(function(value) {
// success
}, function(error) {
// failure
});
then方法可以接受两个回调函数作为参数。第一个回调函数是Promise对象的状态变为resolved时调用,第二个回调函数是Promise对象的状态变为rejected时调用。其中,第二个函数是可选的,不一定要提供。这两个函数都接受Promise对象传出的值作为参数。
接下书写公共js方法 user.js
/**
* 用户的相关服务
*/
const util = require('../utils/util.js');
const api = require('../pages/config/api.js')
/**
* promissin 检测 session_key 是否失效
*/
function checkSessoin () {
// 使用Promise 构造函数
return new Promise(function(resplve, reject){
// 用来检测 用户登录是否失效
wx.checkSession({
success: function() {
resolve(true);
},
fail: function() {
reject(false);
}
})
})
}
/**
* Promise封装wx.login
*/
function login() {
return new Promise(function (resolve, reject) {
wx.login({
success: function (res) {
if (res.code) {
resolve(res);
} else {
reject(res);
}
},
fail: function (err) {
reject(err);
}
});
});
}
/**
* 调用微信登录
*/
function loginByWeixin(userInfo) {
return new Promise(function (resolve, reject) {
return login().then((res) => {
//登录远程服务器
util.request(api.AuthLoginByWeixin, {
code: res.code,
userInfo: userInfo
}, 'POST').then(res => {
if (res.errno === 0) {
//存储用户信息
wx.setStorageSync('userInfo', res.data.userInfo);
wx.setStorageSync('token', res.data.token);
resolve(res);
} else {
reject(res);
}
}).catch((err) => {
reject(err);
});
}).catch((err) => {
reject(err);
})
});
}
/**
* 判断用户是否登录
*/
function checkLogin() {
return new Promise(function(resolve, reject) {
if (wx.getStorageSync('userInfo') && wx.getStorageSync('token')) {
checkSession().then(() => {
resolve(true);
}).catch(() => {
reject(false);
});
} else {
reject(false);
}
})
}
// 开放出去
module.exports = {
loginByWeixin,
checkLogin,
login
}
config.js — > 装载请求后台的接口
// 服务器地址
//var WxApiURL = 'http://localhost:8020/'
var WxApiURL = 'http://127.0.0.1:8020//'
// 装载请求服务器的地址
module.exports = {
WxRegist: WxApiURL + 'regist',
wxDeviceWarning: WxApiURL + 'warning/page' //告警列表
}
util.js --> 封装wx.request的请求方法
var api = require('../pages/config/api.js');
var app = getApp();
// 时间转化
const formatTime = date => {
const year = date.getFullYear()
const month = date.getMonth() + 1
const day = date.getDate()
const hour = date.getHours()
const minute = date.getMinutes()
const second = date.getSeconds()
return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':')
}
const formatNumber = n => {
n = n.toString()
return n[1] ? n : '0' + n
}
/**
* 封装微信的的request
*/
function request(url, data = {}, method = 'GET') {
return new Promise(function(resolve, reject) {
wx.request({
url: url,
data: data,
method: method,
header: {
'Content-Type': 'application/json'
// 'X-Litemall-Token': wx.getStorageSync('token')
},
success: function(res) {
if (res.statusCode == 200) {
if (res.statusCode == 500) {
// 清除登录相关内容
try {
wx.removeStorageSync('userInfo');
wx.removeStorageSync('token');
} catch (e) {
// Do something when catch error
}
// 切换到登录页面
wx.navigateTo({
url: ''
});
} else {
resolve(res.data);
}
} else {
reject(res.message)
}
},
fail: function(err) {
reject(err)
}
})
}).catch((e) => { }) //记住要加上catch 不然在请求的时候报 Uncaught (in promise)
}
module.exports = {
formatTime,
request,
redirect,
showErrorToast
}
其中如果我们封装校验和验证的方法也是如此,最后用module.exports 开发出去,当我们哪个页面需要使用的时候直接引入js即可.
– 关于微信小程序自定义组件的方法
需要我们创建Component
wxml代码页面的样式可以自定义如下代码:页面上{{}}中包含的值都是接下来组件使用的属性,这样我们就可以充分的将该组件完全自由化
<view class="mask" hidden="{{flag}}">
<view class="view">
<view class="model_class"><image class="img_model" src="{{src}}"></image></view>
<view class="model_text">{{ title }}</view>
<view class="model_bottom">
<view class="model_confirem" bindtap='_success'>{{btn_ok}}</view>
<view class="border"></view>
<view class="model_cancel" bindtap='_error'>{{btn_no}}</view>
</view>
</view>
</view>
js代码: 在注释中可以了解到如何在其他页面引入该模态框组件的使用,
首先在要使用该模态框的json文件中引入模态框的组件
然后在页面去使用该模态的组件
// pages/model/model.js
/**
* 模态框组件使用方法
* 1: 首先在使用的页面的json中引入 因为没有单独拿出来作为组件的文件夹
* "usingComponents": {
"model": "/pages/model/model"
}
* 2: 在页面中使用
*
*
*/
Component({
/**
* 组件的属性列表
*/
properties: {
title: { // 属性名
type: String, // 类型(必填),目前接受的类型包括:String, Number, Boolean, Object, Array, null(表示任意类型)
value: '标题' // 属性初始值(可选),如果未指定则会根据类型选择一个
},
src: {
type: String,
value: '../images/pic_unbind.png'
},
btn_no: {
type: String,
value: '取消'
},
btn_ok: {
type: String,
value: '确定'
}
},
/**
* 组件的初始数据
*/
data: {
flag: true
},
/**
* 组件的方法列表
*/
methods: {
//隐藏弹框
hidePopup: function () {
this.setData({
flag: !this.data.flag
})
},
//展示弹框
showPopup() {
this.setData({
flag: !this.data.flag
})
},
_error() {
//触发取消回调 triggerEvent 触发回调事件 bingd:error 触发error,我们在这边可以打印this中可以找到属性triggerEvent 在属性里面可以找到回调的方法
this.triggerEvent("error")
},
_success() {
//触发成功回调
this.triggerEvent("success");
}
}
})
json文件中配置:
{
"component": true,
"usingComponents": {}
}
样式: mask.样式是弹框蒙版,这是一个模态框的组件,用来确定和取消的模态框组件
/* pages/model/model.wxss */
.mask {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
display: flex;
justify-content: center;
align-items: center;
background-color: rgba(0,0,0,0.4);
z-index: 9999;
}
.view {
display: flex;
flex-direction: column;
width: 250px;
height: 215px;
background-color: #fff;
border-radius: 4px;
}
.img_model {
height: 110px;
width: 120px;
}
.model_class {
padding-top: 30rpx;
text-align: center;
}
.model_text {
font-family: PingFang-SC-Medium;
font-size: 16px;
color: #171717;
text-align: center;
}
.model_bottom {
width: 250px;
height: 48px;
display: flex;
flex-direction: row;
margin-top: 38rpx;
justify-content: space-around;
border-top: 1rpx solid #E5E5E5;
}
.model_confirem {
line-height: 78rpx;
color: #2DD5D5;
font-family: PingFang-SC-Medium;
font-size: 16px;
padding-left: 50rpx;
}
.model_cancel {
line-height: 78rpx;
color: #6C6C6C;
font-family: PingFang-SC-Medium;
font-size: 16px;
padding-right: 50rpx;
}
.border {
border: 1rpx solid #E5E5E5;
}
.hover-class {
opacity: 0.5;
background: #D6DAD6
}
小程序样式:
在wxss中
page{
background: red; // 可以定义整个页面的背景颜色
}
在wxml上定义hover-class属性可以出发点击效果
flex属性:
请移步: Flex 布局教程:语法篇
http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html?utm_source=tuicool
CSS 定位详解:
添加链接描述