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开发微信小程序
最近公司部门负责人提出需求需要开发一款微信小程序,由于本人之前是做前端开发的,对于小程序开发一窍不通,但是很多时候我们都是把不会做变成我会学.于是便在网上寻找小程序开发教程,相比于相生的小程序开发,本 ...
随机推荐
- hhhhh臭不要脸//捂脸)多不好意思啊you进步惹
如题↑↑↑ 千万不要相信题目 还是看图说话吧↓↓↓ 我真的蒟蒻啊,,,准确率在70边缘徘徊,卑微☹ 不过还是侥幸地进入了前 30 名! 今天七夕欸,然鹅,,, qq空间里面弥漫着恋爱的酸臭味 香气,‘ ...
- nRF51822 硬件复位引脚
nRF51822 有一个硬件复位引脚和Debug 口SWDIO是共用的,名字叫做nReset. 实现硬件复位是怎样子的: 1.这个引脚引出来, 2.给这个引脚低电平, 3.从低电平拉到高电平,即复位. ...
- 卸载nginx之后重新安装
Ubuntu 14.04上卸载nginx之后重新安装没有重新生成配置文件的解决方法 在配置nginx做实验时配置错了,导致访问不了虚拟主机.一狠心把nginx的配置文件目录(/etc/nginx)都删 ...
- 数据仓库DW、ODS、DM概念及其区别
整体结构 在具体分析数据仓库之前先看下一下数据中心的整体架构以及数据流向 数据中心整体架构.png DB 是现有的数据来源,可以为mysql.SQLserver.文件日志等,为数据仓库提供数据来源 ...
- Python绘制3D图形
来自:https://www.jb51.net/article/139349.htm 3D图形在数据分析.数据建模.图形和图像处理等领域中都有着广泛的应用,下面将给大家介绍一下如何使用python进行 ...
- VMware7.1安装教程
VMWare是一个"虚拟PC"软件公司.它的产品可以使你在一台机器上同时运行二个或更多Windows.DOS.LINUX系 统.与"多启动"系统相比,VMWar ...
- plsql查询数据库-中文显示问号问题
解决方法: 设置本地环境变量 :NLS_LANG=AMERICAN_AMERICA.ZHS16GBK https://blog.csdn.net/github_38358734/article/det ...
- Ingress-nginx 部署使用
Ingress-nginx 部署使用 一.Ingress 简介 在Kubernetes中,服务和Pod的IP地址仅可以在集群网络内部使用,对于集群外的应用是不可见的.为了使外部的应用能够访问集群内 ...
- Linux_CentOS 内存、cpu、进程、端口、硬盘管理
内存.cup 管理 top 命令 top 1.top 命令的第一行: top - :: up :, users, load average: 0.00, 0.02, 0.05 依次对应:系统当前时间 ...
- MongoDB学习(附录一) 安装mongodb3.6时碰到的问题
1.Installing MongoDB Compass...(this may take a few minutes)这一步,会停留很长时间,点击取消可能也取消不了. 安装mongdodb ,进度卡 ...