1. 系统或浏览器判断相关
// common.js
// 判断ios和安卓系统
isSystem(e) {
let u = navigator.userAgent
let isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1 // android终端
if (isAndroid) {
return 'android'
}
return 'ios'
},
// 判断微信浏览器类型
checkPlatform() {
if (/MicroMessenger/i.test(navigator.userAgent)) {
// 这是微信平台下浏览器
return 'Messenger'
}
if (/android/i.test(navigator.userAgent)) {
// 这是Android平台下浏览器
return 'Android'
}
if (/iphone os/i.test(navigator.userAgent)) {
// 这是iOS平台下浏览器
return 'iOS'
}
if (/Linux/i.test(navigator.userAgent)) {
// 这是Linux平台下浏览器
return 'Linux'
}
if (/Linux/i.test(navigator.platform)) {
// 这是Linux操作系统平台
return 'Linux'
}
},
// 判断iphone底部黑线类型手机 iPhoneX,iPhone XS Max,iPhoneXR,iphone11
isIphoneX() {
// iPhone X、iPhone XS
const isIPhoneX = /iphone/gi.test(window.navigator.userAgent) && window.devicePixelRatio && window.devicePixelRatio === 3 && window.screen.width === 375 && window.screen.height === 812
// iPhone XS Max iphone11 Pro
const isIPhoneXSMax = /iphone/gi.test(window.navigator.userAgent) && window.devicePixelRatio && window.devicePixelRatio === 3 && window.screen.width === 414 && window.screen.height === 896
// iPhone XR iphone11
const isIPhoneXR = /iphone/gi.test(window.navigator.userAgent) && window.devicePixelRatio && window.devicePixelRatio === 2 && window.screen.width === 414 && window.screen.height === 896
if (isIPhoneX || isIPhoneXSMax || isIPhoneXR) return true
return false
},
2. 常用数据验证(正则及非正则)
// common.js
// 检验手机号码
validPhone (num) {
num = Number(num)
let phoneReg = /^((\+?86)|(\(\+86\)))?(13[0123456789][0-9]{8}|15[0123456789][0-9]{8}|14[0123456789][0-9]{8}|17[0123456789][0-9]{8}|18[0123456789][0-9]{8}|16[0123456789][0-9]{8}|19[0123456789][0-9]{8})$/
return phoneReg.test(num)
},
// 验证手机号码和固话
validAllPhone(num) {
let phoneReg = /^((\+?86)|(\(\+86\)))?(13[0123456789][0-9]{8}|15[0123456789][0-9]{8}|14[0123456789][0-9]{8}|17[0123456789][0-9]{8}|18[0123456789][0-9]{8}|16[0123456789][0-9]{8}|19[0123456789][0-9]{8})$/
let isfixed = /^([0-9]{3,4})?[0-9]{7,8}$|^0\d{2,3}-\d{7,8}$/
return phoneReg.test(num) || isfixed.test(num)
},
// 验证物流号
validateLogisticsNo (logisticsNo) {
if (!/[a-z-A-Z-0-9]{1,30}$/.test(logisticsNo)) {
return false
}
return true
},
// 验证银行卡号
formatBankNo(BankNo) {
let numberBankNo = parseInt(BankNo.replace(/\s/g, ''))
console.log(numberBankNo)
if (/^[0-9]{16}$|^[0-9]{19}$/.test(numberBankNo)) {
return true
}
return false
},
// 验证税号(15或者17或者18或者20位字母、数字组成)
checkTax(obj) {
if (obj !== '' && obj != null) {
return true
}
return false
},
// 验证邮箱
isEmail(str) {
let reg = /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(.[a-zA-Z0-9_-])+/
if (reg.test(str)) {
return true
}
return false
},
// 验证身份证号码
isIdentifyCardNo(str) {
let reg = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/
if (reg.test(str)) {
return true
}
return false
},
// 验证纯数字
isNumber(str) {
let reg = /^[0-9]*$/
if (reg.test(str)) {
return true
}
return false
},
// 验证是否有表情包输入
checkEmoji(str) {
let reg = /[^\u0020-\u007E\u00A0-\u00BE\u2E80-\uA4CF\uF900-\uFAFF\uFE30-\uFE4F\uFF00-\uFFEF\u0080-\u009F\u2000-\u201f\u2026\u2022\u20ac\r\n]/g
if ((typeof str === 'string') && str.match(reg)) {
return false
}
return true
},
/***
* 判断数据类型
* @param val 当前验证数据
* @param type 想要验证的数据类型Object, Array ,Undefined, Null, Boolean, Number和String
*/
isJsType(val, type) {
return Object.prototype.toString.call(val) === `[object ${type}]`
},
// 判断对象是否为空
isNull(data) {
if (data == null || data == '' || typeof (data) === 'undefined') {
return true
}
return false
},
3. H5备用方法
// h5页面跳转到外链还能返回到当前页面的方法
jumpPage() {
let url = 'https://github.com/xszi'
let webPath = encodeURIComponent(location.href)
window.location.href = url + '&returnUrl=' + webPath
}
// 深拷贝
deepCopy(obj) {
let result = Array.isArray(obj) ? [] : {}
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
if (typeof obj[key] === 'object' && obj[key] !== null) {
result[key] = utils.deepCopy(obj[key]) // 递归复制
} else {
result[key] = obj[key]
}
}
}
return result
},
4. axios拦截请求响应, 简化get,post请求方法
// request.js
'use strict'
import axios from 'axios'
import storage from './localStorage.js'
import store from '../store/store.js'
import router from '../router/index.js'
import {
Toast
} from 'vant'
const baseURL = process.env.NODE_ENV === 'development' ? '/api' : '/mall/def'
export let mallAxios = axios.create({
// 基础URL
baseURL,
// 响应超时时间
timeout: 20000
})
// 请求拦截处理函数
let reqIntercept = (config) => {
const token = localStorage.getItem('token')
// 配置usBusId
if (store.state.busId) {
config.headers['ucBusId'] = store.state.busId
}
// 配置token
if (token) {
config.headers['ucToken'] = token
}
// 在发送请求之前做些什么
// config.headers['ucBusId'] = '4856'
// config.headers['ucToken'] = '119'
return config
}
// 请求拦截错误时的处理函数
let reqErrorIntercept = (error) => {
// 对请求错误做些什么
return Promise.reject(error)
}
// 给mallAxios实例添加 请求拦截器
mallAxios.interceptors.request.use(reqIntercept, reqErrorIntercept)
// 响应拦截处理函数
let resIntercept = (response) => {
// 请求状态码
const status = response.status
if (status === 200) {
// if (response.data.status === 500) {
// Toast(response.data.message)
// return
// }
handleErrCode(response.data)
return Promise.resolve(response.data)
} else {
return Promise.reject(response)
}
}
// 响应拦截错误时的处理函数
let resErrorIntercept = (error) => {
// 断网或者请求超时状态
if (!error.response) {
if (error.message.includes('timeout')) {
Toast({
message: '网络请求超时',
duration: 1500
})
console.log('网络超时')
} else {
Toast({
message: '网络开小差了',
duration: 1500
})
console.log('网络异常,请检查网络是否已连接')
}
} else {
const status = error.response.status
switch (status) {
// 401 未登录
case 401:
break
case 403:
break
case 404:
Toast({
message: '网络请求不存在',
duration: 1500
})
console.log('网络请求不存在')
break
default:
Toast({
message: error.response.data || error.response.data.message,
duration: 1500
})
console.log(error.response.data.message)
}
}
// 对响应错误做点什么
return Promise.reject(error)
}
// 响应拦截器
mallAxios.interceptors.response.use(resIntercept, resErrorIntercept)
/**
* 处理code 为 1001 会员卡购买跳转 1004 商家过期等
* @Date 2019/11/13
* @param data
*/
function handleErrCode(data) {
// code==1 status=500 服务器错误
if (data.code === 1) {
Toast({
message: data.message,
duration: 1500
})
return false
}
if (data.code === -98) {
router.push(`/bus-expires`)
}
// -100 表示未登录,请授权 -101 没绑定电话要绑定电话
if (data.code === -100) {
// 清除token
storage.remove('token')
store.dispatch('getAuthor')
return false
}
if (data.code === -101) {
store.commit('showPhoneDialog', true)
return false
}
// 添加全局报错处理
if (data.code !== 0 && data.code !== 10700 && data.code !== 10800) {
Toast(data.message)
return false
}
return true
}
// 简化get请求
// get, delete请求所需的参数跟post, put等不一样, 需要单独处理, 具体请参考axios文档
export let get = async (url = '', params = {}, config = {}) => mallAxios.get(url, {
params,
...config
})
// 简化post请求
export let post = async (url = '', params = {}, config = {}) => mallAxios.post(url, params, config)
5. H5请求微信授权登录,调用微信JS-SDK,实现图片预览放大,分享和保存,使用微信的拍照,选图,语音,位置等手机系统功能。
// wxSdk.js
import {
request
} from './service.js'
import wx from 'weixin-js-sdk'
export default function getWXSign(busId, url, isHideMenuItems) {
return new Promise((resolve, reject) => {
request.getWXConfig({ // 这是请求后台的地址
busId,
url
})
.then(function (res) {
if (res.code === 0 && res.data) {
const data = res.data // 返回wx.config需要的参数
let jsApiList = ['updateAppMessageShareData', 'updateTimelineShareData', 'chooseImage', 'previewImage', 'hideAllNonBaseMenuItem', 'showAllNonBaseMenuItem', 'getLocation', 'openLocation']
if (isHideMenuItems) jsApiList = ['hideMenuItems']
wx.config({
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: data.appId, // 必填,企业号的唯一标识,此处填写企业号corpid
timestamp: data.timestamp, // 必填,生成签名的时间戳
nonceStr: data.nonceStr, // 必填,生成签名的随机串
signature: data.signature, // 必填,签名,见附录1
jsApiList // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
})
} else {
resolve(res)
return
}
wx.ready(function () {
resolve(res)
})
wx.error(function (res) {
resolve(res)
// config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
})
})
.catch(function (error) {
reject(error)
})
})
}
// 隐藏所有非基础按钮接口
// wx.hideAllNonBaseMenuItem();
// “基本类”按钮详见附录3
// 显示所有功能按钮接口
// wx.showAllNonBaseMenuItem();