mpvue + vant + flyio 小程序项目总结
vant 的使用
我开始是 npm 导入,然后 import,使用不了。
找了各种方法,最后还是下载文件,然后找到 dist 文件夹,复制到项目里,我是放在 static 文件夹,文件名 dist 重命名为 vant。
在 app.json 里添加需要的组件,这是全局添加的,可以全局使用这些组件
"usingComponents": {
"van-button": "../static/vant/button/index",
"van-cell": "../static/vant/cell/index",
"van-cell-group": "../static/vant/cell-group/index",
"van-radio": "../static/vant/radio/index",
"van-radio-group": "../static/vant/radio-group/index",
"van-transition": "../static/vant/transition/index"
}
flyio 的使用
以前用的 axios,也没有仔细研究过,这次自己封装头痛不已。
我们使用 token 做登录信息(id 在 token 里面),做了一个单独的登录接口,获取 token,token 存在本地,并且 token 会过期。
接口自动判断是否需要 token ,如果需要就去拿,放在 header 里发过去,header 里添加新字段,如果有特殊字符比如下划线等,就需要 nginx 配置,比较不麻烦,驼峰命名比较方便。
如果本地没有 token 数据,就需要先暂停请求,重新获取 token,然后继续之前的请求。
如果响应返回 token 过期,就需要重新获取 token ,并且重新自动发起之前的请求。
请求与 token 之间的矛盾(fly 的暂停是使用拦截器的锁死,拦截器都停了,获取 token 的接口自然也就用不了了),我们需要在封装的时候把获取 token 的接口单独使用 fly 对象。
import Fly from 'flyio/dist/npm/wx'
import {
_GetToken
} from "@/api/apiList"; const tokenFly = new Fly();
tokenFly.config.timeout = 10000; //设置超时
tokenFly.config.baseURL = process.env.API_ROOT; //填写域名 // 添加请求拦截器
tokenFly.interceptors.request.use(request => {
request.headers = {
"X-Tag": "flyio",
'Content-Type': "application/x-www-form-urlencoded",
};
return request
}, error => {
Promise.reject(error)
}) // 添加响应拦截器
tokenFly.interceptors.response.use(response => {
// 统一处理一些响应的code状态
if (response.data.data.loginToken) {
wx.setStorage({
key: "token",
data: response.data.data.loginToken
})
} return response.data
}, err => {
// 请求出错,根据返回状态码判断出错原因
if (err.status == 0) {
wx.showToast({
title: `网络连接异常`,
icon: 'none',
duration: 5000
})
} else if (err.status == 1) {
wx.showToast({
title: `网络连接超时`,
icon: 'none',
duration: 5000
})
} else if (err && err.response) {
wx.showToast({
title: `连接错误,请稍后再试! ${err.response.status}`,
icon: 'none',
duration: 5000
})
}
return Promise.resolve(err)
}) const fly = new Fly()
fly.config.timeout = 10000; //设置超时
fly.config.baseURL = process.env.API_ROOT; //填写域名 // 添加请求拦截器
fly.interceptors.request.use(request => {
request.headers = {
"X-Tag": "flyio",
'Content-Type': "application/x-www-form-urlencoded",
}; let url = request.url;
if (url.indexOf("login") > -1) {
wx.removeStorageSync('token')
request.headers.loginToken = "";
}
if (url.indexOf("user") > -1 && url.indexOf("login") < 0) {
if (!wx.getStorageSync('token')) {
console.log('没有token,先请求token...');
fly.lock(); //锁定当前实例,后续请求会在拦截器外排队
return getToken().then(() => {
wx.hideLoading()
request.headers.loginToken = wx.getStorageSync('token');
return request
})
.finally(() => {
fly.unlock() // 解锁当前fly实例
})
} else {
request.headers.loginToken = wx.getStorageSync('token');
}
}
return request
}, error => {
Promise.reject(error)
}) // 添加响应拦截器
fly.interceptors.response.use(response => {
// 统一处理一些响应的code状态
if (response.data.data.loginToken) {
wx.setStorage({
key: "token",
data: response.data.data.loginToken
})
}
if (response.data.code == -2) {
wx.showLoading({
title: '本地登录已失效'
})
console.log('本地已有token失效,即将请求新的token')
fly.lock() // 锁定当前fly实例
return getToken().then(() => {
wx.hideLoading()
console.log('token已更新')
})
.finally(() => {
fly.unlock() // 解锁当前fly实例
})
.then(() => {
console.log(`重新请求:path:${response.request.url},baseURL:${response.request.baseURL}`)
return fly.request(response.request)
})
}
return response.data
}, err => {
// 请求出错,根据返回状态码判断出错原因
if (err.status == 0) {
wx.showToast({
title: `网络连接异常`,
icon: 'none',
duration: 5000
})
} else if (err.status == 1) {
wx.showToast({
title: `网络连接超时`,
icon: 'none',
duration: 5000
})
} else if (err && err.response) {
wx.showToast({
title: `连接错误,请稍后再试! ${err.response.status}`,
icon: 'none',
duration: 5000
})
}
return Promise.resolve(err)
}) const getToken = () => {
return new Promise((resolve) => {
wx.getUserInfo({
success: function (infoRes) {
console.log(infoRes);
wx.login({
success(loginRes) {
console.log(loginRes);
if (loginRes.code) {
wx.showLoading({
title: '正在重新登录'
})
tokenFly.post('/pub/api/login', {
code: loginRes.code,
encryptedData: infoRes.encryptedData,
iv: infoRes.iv,
parentId: wx.getStorageSync("fromId") || ""
}).then((flyReq) => {
console.log(flyReq);
console.log("token请求成功")
wx.showLoading({
title: '重新登录已完成'
})
resolve()
})
} else {
console.log("登录失败!" + loginRes.errMsg);
}
}
});
},
fail: function (res) {
console.log(res);
wx.navigateTo({
url: "../auth/main"
});
}
});
})
} export default fly
mpvue 的使用
- 在 pages 里新建页面,每个页面都是单独文件夹,里面有一个 index.vue 和 main.js。页面写在 index.vue 中,main.js 不需要更改。
- 全局 css 和 iconfont 图标放在 assets 文件夹内,在 main.js 中导入就好了。
- 在 app.json 里,页面的路径应该写成 "pages/xxx/main",在页面中,路径的跳转相对路径("../xxx/main")。
页面之间的传参
// 页面跳转带参
wx.navigateTo({
url: `../exercise/main?levelId=${item.id}`
}); // 页面路径参数获取
this.$root.$mp.query.levelId
图片的样式
height 不会自适应,我添加了原生小程序的 mode 属性,实在不行就设置 height 吧。
按钮 bind 绑定的写法
按钮的原生属性 bindxxxxxxxxx,bind 在 mpvue 中写成 @ 就好了,
<button open-type="getUserInfo" @getuserinfo="getAuth" class="auth-btn">开始使用</button>
生命周期
生命周期 destory 和 onUnlod,页面之间的切换,如果之前的页面有弹出框,切换到其他的页面然后再返回,这个弹出框还是显示的,之前的页面的数据是没被销毁的。
登录授权
小程序改版之后,wx.getUserInfo 不会弹出授权框了,需要用户手动触发。我们做了一个授权页,在首页进入下一个页面的时候,判断本地是否有个人信息,如果没有就去拿用户信息,如果失败就去授权页。
// 判断去授权页
goMajorPath() {
// console.log(item);
let that = this;
if (this.wxUserInfo && this.xfxUserInfo) {
wx.navigateTo({
url: `../major/main`
});
return;
} // 拿用户信息,失败就去授权
wx.getUserInfo({
success: function(infoRes) {
console.log(infoRes);
that.CURMAJOR(item);
that.WXUSERINFO(infoRes.userInfo); // 存储用户信息 wx.navigateTo({
url: `../major/main`
});
},
fail: function(res) {
console.log(res);
wx.navigateTo({
url: "../auth/main"
});
}
});
}
// 授权逻辑
getAuth(e) {
let that = this;
if (e.mp.detail.userInfo) {
console.log("授权通过");
wx.hideToast();
this.WXUSERINFO(e.mp.detail.userInfo); // 存储用户信息
this.action_XFXUSERINFO();
wx.navigateBack({
delta: 1
});
} else {
console.log("拒绝授权");
wx.showToast({
title: "鉴于您拒绝授权,我们是无法保存您的答题数据的!",
icon: "none",
duration: 5000
});
}
}
手机号获取
获取手机号,也是单独做了一个页面,手动触发获取手机号
// 去手机号获取页
goLevelPath(item) {
console.log(item);
console.log(this.xfxUserInfo.phone);
let that = this;
if (this.xfxUserInfo.phone) {
that.CURMAJOR(item);
wx.navigateTo({
url: `../level/main?majorId=${item.id}`
});
return;
} //没有手机号跳转请求页面
wx.navigateTo({
url: "../phone/main"
});
}
// 手机号获取
getPhone(e) {
// console.log(e);
// console.log(e.mp.detail);
if (e.mp.detail.errMsg == "getPhoneNumber:ok") {
this.action_savePhone(e.mp.detail);
this.action_XFXUSERINFO();
wx.navigateBack({
delta: 1
});
} else {
console.log("拒绝授权");
wx.showToast({
title: "鉴于您拒绝快捷登录,我们是无法保存您的答题数据的!",
icon: "none",
duration: 5000
});
}
}
分享
此功能实现传播,也算是核心业务了。分为顶部按钮分享和自定义按钮分享。需要在 mounted 生命周期设置分享功能,在 onShareAppMessage 生命周期写业务。自定义按钮需设置 open-type="share"
mounted() {
wx.showShareMenu({
withShareTicket: true
});
},
onShareAppMessage: function(res) {
console.log(res); //menu 没有 tartget
if (res.from === "button") {
return {
title: `恭喜${this.xfxUserInfo.username},挑战[${
this.curMajor.name
}]专业-${this.curLevel.levelName}${
this.coreNum >= 80 ? "成功!" : "完成,请再接再厉!"
}`,
path: `/pages/index/main?fromId=${this.xfxUserInfo.id}`
};
}
if (res.from === "menu") {
return {
title: "一起打卡学习,每天进步一点点",
path: `/pages/index/main?fromId=${this.xfxUserInfo.id}`
};
}
}
分享的传播标记,分享的路径是可以带参的,这个参数就是分享传播者的标记,当新用户从这里进来,路径中是有这个标记的,我们直接在 App.vue 的 onLaunch 生命周期中,存储改标记到本地,当用户授权的时候和用户信息一起存起来。该生命周期还可以判断场景值,我是直接判断的参数。
onLaunch(opt) {
console.log(opt);
if (opt.query.fromId) {
wx.setStorage({
key: "fromId",
data: opt.query.fromId
});
}
},
迭代更新
onLaunch(opt) {
//调用微信接口检查是否有新版本
const updateManager = wx.getUpdateManager(); updateManager.onCheckForUpdate(function (res) {
// 请求完新版本信息的回调
console.log(res.hasUpdate);
}); updateManager.onUpdateReady(function () {
wx.showModal({
title: "更新提示",
content: "新版本已经准备好,是否重启应用?",
success: function (res) {
if (res.confirm) {
// 新的版本已经下载好,调用 applyUpdate 应用新版本并重启
updateManager.applyUpdate();
}
}
});
}); updateManager.onUpdateFailed(function () {
// 新版本下载失败
wx.showModal({
title: "更新提示",
content: "新版本下载失败",
showCancel: false
});
});
},
mpvue + vant + flyio 小程序项目总结的更多相关文章
- 微信小程序搭建mpvue+vant+flyio
导语 上一篇文章微信小程序搭建mpvue+vant已经介绍了如何搭起mpvue项目及引入vant,本篇文章继续在它的基础上,引入flyio,并做一些封装,目的是为了在小程序发起请求. 这时读者会有些疑 ...
- 基于mpvue搭建小程序项目框架
简介: mpvue框架对于从没有接触过小程序又要尝试小程序开发的人员来说,无疑是目前最好的选择.mpvue从底层支持 Vue.js 语法和构建工具体系,同时再结合相关UI组件库,便可以高效的实现小程序 ...
- 如何把原生小程序项目合并的mpvue项目中
当时的情景是这样的: 使用mpvue写微信小程序,写着写着项目写到一半了,突然间不想这样继续写了,想切换回原生小程序语法去写剩余部分. 如下图,红色框里的功能是已经用mpvue完成的功能,绿色框部分的 ...
- 《微信小程序项目开发实战:用WePY、mpvue、Taro打造高效的小程序》(笔记1)WePY开发环境的安装
WePY的安装或更新都通过npm进行,全局安装或更新WePY命令行工具,使用以下命令: npm install wepy-cli -g 稍等片刻,成功安装后,即可创建WePY项目. 注意:如果npm安 ...
- 微信小程序项目开发实战:用WePY、mpvue、Taro打造高效的小程序》(笔记4)支持React.js语法的Taro框架
Taro本身实现的情况类似于mpvue,mpvue的未来展望中也包含了支付宝小程序,现在的版本中,也可以使用不同的构建命令来构建出百度小程序的支持,如第10章所示,但是现在Taro先于mpvue实现了 ...
- mpvue开发小程序项目遇到的问题
mpvue项目 最近用mpvue开发了一个家庭私人医生签约的小程序项目.记录总结一下,开发过程中遇到的一些问题. 关于页面进栈出栈的状态值问题 页面进出栈,会触发onLoad/unLoad事件.出栈不 ...
- 使用mpvue开发微信小程序
更多内容请查看 我的新博客 地址 : 前言 16年小程序刚出来的时候,就准备花点时间去学学.无奈现实中手上项目太多,一个接着一个,而且也没有开发小程序的需求,所以就一拖再拖. 直到上周,终于有一个小程 ...
- mpvue体验微信小程序开发
微信小程序 https://developers.weixin.qq.com/miniprogram/introduction/index.html?t=18082114 微信小程序是一种全新的连接用 ...
- 利用mpvue开发微信小程序
最近公司部门负责人提出需求需要开发一款微信小程序,由于本人之前是做前端开发的,对于小程序开发一窍不通,但是很多时候我们都是把不会做变成我会学.于是便在网上寻找小程序开发教程,相比于相生的小程序开发,本 ...
随机推荐
- 行业大秀:EasyEarth Show!
EasyEarth三维可视化地理信息云平台是由北京四维益友信息技术有限公司自主研发的新一代面向三维可视化应用领域的基础信息系统平台. EasyEarth以数据管理为核心,围绕7大类基础数据,提供综合管 ...
- hadoop jps 出现空指针错误
在hadoop中安装jdk软件以后出现如下问题: 错误描述 [xxx@localhost jdk1..0_181]$ ./bin/jps Exception in thread "main& ...
- app内嵌H5的上传图片的功能
1.上传组件 <!-- - hasBorder {Boolean} cell底部边框,oneline 为 true 有效 - inlineBorder {Boolean} cell底部短边框 - ...
- RPC接口测试(二) RPC 与HTTP的区别
RPC 与HTTP的相同点 两种风格的API区别,总结一下其实非常简单: 1,RPC面向过程,只发送 GET 和 POST 请求.GET用来查询信息,其他情况下一律用POST.请求参数是动词,直接描述 ...
- phpstudy apache 服务无法启动
1.找到apache路径 3.打开cmd进入bin文件夹 4.输入 httpd.exe 看报的什么错误即可解决 我的这边是httpd.config 里面配置了个项目文件夹路径,这个文件夹被我删了,导 ...
- cas 3.5.3服务器搭建+spring boot集成+shiro模拟登录(不修改现有shiro认证架构)
因为现有系统外部接入需要,需要支持三方单点登录.由于系统本身已经是微服务架构,由多个业务独立的子系统组成,所以有自己的用户认证微服务(不是cas,我们基础设施已经够多了,现在能不增加就不增加).但是因 ...
- net use命令详解(转)
net use命令详解 1)建立空连接: net use \\IP\ipc$ "" /user:"" (一定要注意:这一行命令中包含了3个空格) 2)建立非空连 ...
- pycharm安装pyinstaller将pygame打包成exe
首先,使用pycharm自带的下载包工具,File-Settings-Project Interpreter,如图: 安装完成后,发现安装到了Python根目录下,我的在C:\python34\Scr ...
- matlab学习笔记11_2高维数组操作 squeeze,ind2sub, sub2ind
一起来学matlab-matlab学习笔记11 11_2 高维数组处理和运算 squeeze, ind2sub, sub2ind 觉得有用的话,欢迎一起讨论相互学习~Follow Me squeeze ...
- LD SCore计算基因多效性、遗传度、遗传相关性(the LD Score regression intercept, heritability and genetic correlation)
这篇文章是对之前啊啊救救我,为何我的QQ图那么飘(全基因组关联分析)这篇文章的一个补坑. LD SCore除了查看显著SNP位点对表型是否为基因多效性外,还额外补充了怎么计算表型的遗传度和遗传相关性. ...