入职新公司第一个月,给了一个小程序的任务,就一个前端的公司真的是说自由也自由,有好也有坏吧。 好处就是看原生的小程序文档看的我难受,就研究了一波用 vue 写,于是找到了 Uni-app 刚开始写,官方建议使用 HbuildeX ,用了一番,(其实打开这个 IDE 就不想用了)
一. 开发前的准备
- vue 脚手架
- 微信开发者工具
上面这些自己安去,啦啦啦
二. vscode 中开发
装个插件先
由于使用小程序 api,建议装一个小程序开发助手的 vscode 插件
第一个插件,enmm,忽略(我是来写代码的,不是摸鱼的)
当然,还要装 vue 的语法检验插件 Vetur(你肯定装了,都想用 vue 写小程序了嘛)
开始开发
先看一下长啥样(忽略美观,毕竟,没有专门的 UI,我是一个没有美感的前端小哥哥)
一. 创建项目
打开你爱的 powershell,写上
vue create -p dcloudio/uni-preset-vue mygreatepro
// 后面是随便你的名字
选模板,默认模板,回车就好啦,你喜欢 TS 你就选 TS 的咯(谁能教教我怎么写 TS 呀,大佬们)
然后等等等,看到
别听他的,我们要写的是小程序,应该进入项目文件夹然后执行
npm run dev:mp-weixin // 开发阶段
npm run build:mp-weixin // 发布阶段
二、开始干活
1. 用 vscode 打开你创建的项目文件夹
除了那几个文件,其他的跟脚手架创建的项目都长得一样嘛,更熟悉嘛,舒服(我就是讨厌微信小程序原生框架怎么了)
2. 在开发者工具中预览
刚刚我们执行了 npm run dev:mp-weixin 后 就可以直接打开开发者工具,导入项目了
appid 就先别写了,反正也不是在这儿写,引入就好了
如果已经申请好了的话,请用你的 vscode,找 manifest.json 文件打开,找到这个地方
"mp-weixin": { /* 微信小程序特有相关 */
"appid": "这里写appid",
"setting": {
"urlCheck": false
},
"usingComponents": true
}
然后再去预览,看到这样的:
就搞定了
3. 开始开发
先看已经上线的
嫌丑我就打人
1. 分析需求
三个 tab 页,显然还需要登录授权,再加个登录页。
好,先把页面准备好
别忘了 pages.json 里也写好,这样微信才能处理 (微信说的)
因为是 tab 标签,所以还需要配置 pages.json 里的 tabBar
"tabBar": {
"color": "#8a8a8a",
"selectedColor": "#d4237a",
"backgroundColor": "#fff",
"position": "bottom",
"borderStyle": "black",
"list": [
{
"pagePath": "pages/anchor/index",
"text": "主播",
"iconPath": "static/tabar/1-1.png",
"selectedIconPath": "static/tabar/1.png"
},
{
"pagePath": "pages/withdraw/index",
"text": "提现",
"iconPath": "static/tabar/2-1.png",
"selectedIconPath": "static/tabar/2.png"
},
{
"pagePath": "pages/mine/index",
"text": "我的",
"iconPath": "static/tabar/4-1.png",
"selectedIconPath": "static/tabar/4.png"
}
]
}
可以看到对应的静态图片等文件放到 static 下面,但是请注意 css 样式文件不可以放到这里面,否则将不会被编译成 wxss,然后你就会纠结好久,白写了
上面的都写好,没错了,你就可以在开发者工具里看到
这就搞定了。
2. 开扣
我用的是 scss,所以需要 yarn add sass-loader node-sass
dlould 提供了 uni-ui 这个框架,里面有丰富的组件,那就用咯
1. 使用 uni-ui 的步骤
- 安装 yarn add @dcloudio/uni-ui
- 使用 局部引入,注册,使用
建议直接看 npm 上的它 www.npmjs.com/package/@dc…
2. 在我的主播页面用一波
类似一个 tab 标签的组件,这里面叫做分段器
-
-
复制 npm 上的步骤代码
-
import {uniBadge} from '@dcloudio/uni-ui' export default { components: {uniBadge} }
-
-
- 找到对应的要用的组件名 uniSegmentedControl 替换
-
- 去找 html 结构,你可以在插件市场里搜每个你需要的插件的名字 注意不带 uni 前缀
-
- 找到之后,根据文档,放到 template 里使用
注意:坑来了,文档中的处理不同视图切换的点击事件的示例代码
下面用的是 e,上面的参数还是 index,这不是欠打嘛,注意 index 改成 e 就好了
tips:如果发现小程序预览没有改变,可以重新编译一下,有时候引入新组件偶尔会需要重新编译
然后现在预览 发现
就搞定啦
下一篇:
一、登陆授权
1. 小程序的登录机制
-
传统登陆(jwt 方式为例)
-
用户输入用户名密码(密码需要通过某些算法进行加密),访问登录接口
-
后端校验用户名密码,将用户的这些信息加密成一个 token 字符串,返回给前端
-
前端将 token 保存下来(就本地化存储咯,这里涉及一个面试题:localstorage,sessionstorage,cookie 区别是啥?自己问问自己咯)
-
前端每次发请求都带着 token 发给后端,由后端去判断是否合法登录状态(token 怎么传,放在头还是体里自己和后端商量哈)
-
然后前端根据返回情况去判断是否执行什么操作
介绍完这些就不得不提知名的面试题了 cookie,session,token 的区别是啥??? 推荐一篇文章,可以看一下,不了解的小伙伴 juejin.cn/post/684490…
-
-
小程序登录授权 小程序没有登录框,就一个授权使用用户信息,那处理过程是怎么样的呢?简单讲步骤就是: 获取用户信息做授权 ---⇒ 调用 wx.login 接口 ----⇒ 拿到返回的唯一的身份认证 code---⇒ 连 code 带用户信息传给你的后端 ---⇒ 后面就跟上面一样的了
需要注意的是
- code 只能用一次,且五分钟过期,过期就需要重新 wx.login()
2. 我们做登陆授权
2-1、思考场景
在小程序加载之前,判断是否登录过(就是有没有token咯),如果没有登陆过,就跳转登录界面(或者直接调用获取用户信息接口以及登录接口)
2-2 登陆前的判断
在小程序加载之前,判断是否登录,并做对应跳转
如何判断加载之前?----⇒ 生命周期钩子函数
这时,我们打开项目中的 App.vue 会看到以下代码:
onLaunch: function() {
// 这时app初始化完成
// 注意全局只触发一次!!!
console.log('App Launch')
},
onShow: function() {
// app从后台切入前台或者启动
// 显然这是判断是否登陆过的好机会
console.log('App Show')
},
onHide: function() {
// app从前台进入后台
console.log('App Hide')
}
因此判断方式
onShow: function() {
// 查一下都获取了那些权限
wx.getSetting({
success(res) {
// 看看有没有用户信息,如果不存在,证明没有登陆
if (!res.authSetting["scope.userInfo"]) {
// 关闭所有页面,打开到应用内的登录页面
wx.reLaunch({
url: "/pages/authorise/index"
});
}
}
});
},
小程序的页面间跳转相关 api
wx.reLaunch(); // 关闭所有页面,打开到应用内的某个页面
wx.switchTab(); // 跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面
wx.navigateTo(); // 跳转到某个页面
wx.navigateBack(); // 返回到上个页面,需要跟navigateTo配合使用
具体使用方式请参考 wx 文档,实在看不下去就看 uniapp 的文档,长得一个样反正
uniapp 的 api 封装继承了小程序的 api,基本上小程序的 api 前面的 wx 俩字改成 uni 都能用
2-3、登录操作
话不多说,看代码 微信的有些权限的 api 被废弃了,现在只能通过 button 的 opentype 属性来做一些权限操作了 以下代码包括处理用户拒绝授权后的二次引导授权登录过程
<button open-type="getUserInfo" lang="zh_CN" @getuserinfo="mpGetUserInfo" size="mini" v-if="show">授权登录</button>
<button type="primary" size="mini" open-type="openSetting" @opensetting="reauthorize" v-else>重新授权</button>
// 获取到用户信息后,调用登录接口,如果被拒绝授权,就跳转到设置页面
mpGetUserInfo(result) {
const that = this;
// 查看是否授权
wx.getSetting({
success(res) {
if (res.authSetting["scope.userInfo"]) {
// 已经授权,可以直接调用 getUserInfo 获取头像昵称
wx.getUserInfo({
success: function(res) {
that.userInfo = res.userInfo;
wx.login({
success: function(loginRes) {
that.userInfo.code = loginRes.code;
that.$http({
url: "登录接口地址",
data: that.userInfo,
method: "POST"
})
.then(res => {
// 登录失败,提示错误信息,重新打开授权页面
if (判断登录失败的条件) {
wx.redirectTo({
url: ""
});
// 登陆成功
} else {
// 保存登陆成功获取的token
wx.setStorageSync("token", res.data.userinfo.token);
// 保存返回的被处理过的用户信息
uni.setStorageSync("login", res.data.userinfo);
// 登陆成功 跳转到tab首页
wx.switchTab({
url: ""
});
}
});
}
});
}
});
} else {
that.show = false;
}
}
});
},
// 处理重新授权后的回调函数
reauthorize(e) {
if (e.detail.authSetting["scope.userInfo"]) {
// 若二次授权成功,切换对话框的显示按钮
this.show = true;
}
}
这样,就搞定咯,至于那个 this.$http 是啥请看第三篇(我还没写,咋地) 看完,点个赞呗。
继续看 先吐槽一句,三天了,小哥哥还没收到工资,好烦烦哦,咱一起摸鱼吧,朋友们
上回书说到
this.$http 发送请求,这是个啥?
一、PC 端 vue 项目中发请求
傻瓜式步骤:(使用 axios)
yarn add axios
// npm 也行啦
// 在cli项目中
// main.js中
import axios from 'axios'
// 配置请求的根路径
// 这个baseURL如果配置了跨域代理,就把proxy里配的名字给它就成
axios.defaults.baseURL = '/api'
// 配置请求拦截器
axios.interceptors.request.use(config => {
// 这里做各种预处理,加token啦,拦截权限访问啦随便
return config
}, (error) => { return Promise.reject(error) })
axios.interceptors.response.use(config => {
return config
})
// 挂载到vue上
Vue.prototype.$http = axios
二、小程序的请求
1、原生的做法:
wx.request({
url: 'test.php', //仅为示例,并非真实的接口地址
data: {
x: '',
y: ''
},
header: {
'content-type': 'application/json' // 默认值
},
success (res) {
console.log(res.data)
}
})
xue 微有点难受,因为用惯了 axios,支持 promise,那我们就让他支持 promise 呗
2、封装一个支持 promise 的小请求函数
- 1、新建一个 request.js 文件,放到一个叫 utils 的文件夹下(我就不跟你说 utils 啥意思)
- 2、导出一个默认函数对象
- 3、函数返回一个 promise, 里面一个 resolve 一个 reject,不知道 promise 是啥请看小哥哥其他文章哦
export default () => {
return new Promise((resolve,reject)=>{
})
}
- 4、把微信的 api 封装进去(uniapp 的 api 也行,如果有跨端需求,就直接封装 uni 的 requestapi,差不多长得)
export default () => {
return new Promise((resolve,reject)=>{
wx.request({
url: 'test.php', //仅为示例,并非真实的接口地址
data: {
x: '',
y: ''
},
header: {
'content-type': 'application/json' // 默认值
},
success (res) {
console.log(res.data)
}
})
})
}
- 5、继续封装,还没法直接用现在
// 把会改的参数抽出来,像URL啦,methods啦,data数据啦,通过形参的方式传递,把请求的成功或者失败的结果弄出去
export default (params) => {
return new Promise((resolve,reject)=>{
wx.request({
...params
header: {
'content-type': 'application/json' // 默认值
},
success (res) {
resolve(res) // 这里resolve出去的是res还是res.data看你们请求返回的数据
}
fail: (err) => {
reject(err)
},
)
})
}
- 6、axios 有一个 baseURL 省劲儿,咱也得有
export default (params) => {
const baseUrl = "写你自己的地址的公共部分"
return new Promise((resolve, reject) => {
wx.request({
...params,
url: baseUrl + params.url,
success: (res) => {
resolve(res.data)
},
fail: (err) => {
reject(err)
}
});
})
}
- 7、处理请求头
// 比如需要携带token请求的
// 比如需要设置一些字段类型 都在这里搞
export default (params) => {
const baseUrl = "https://www.jianbingkonggu.com/"
let head = {}
if (判断需要加token请求的条件) {
head["token"] = uni.getStorageSync('token');
}
head['Content-Type'] = 'application/x-www-form-urlencoded'
return new Promise((resolve, reject) => {
wx.request({
...params,
url: baseUrl + params.url,
header: head,
success: (res) => {
resolve(res.data)
},
fail: (err) => {
reject(err)
}
});
})
}
完整版
export default (params) => {
const baseUrl = "https://www.jianbingkonggu.com/"
let head = {}
if (!params.url.includes("/MiniProgramLogin")) {
head["token"] = uni.getStorageSync('token');
}
head['Content-Type'] = 'application/x-www-form-urlencoded'
return new Promise((resolve, reject) => {
// 为了让用户看起来更舒服
// 弄一个加载中动画
uni.showLoading({
title: '加载中'
})
wx.request({
...params,
url: baseUrl + params.url,
header: head,
success: (res) => {
resolve(res.data)
},
fail: (err) => {
reject(err)
},
complete: () => {
// 请求完成
// 隐藏加载中的提示框
uni.hideLoading()
}
});
})
}
2、咋在项目中用?
一句话,跟 axios 一样
- 引入
- 挂载
- 使用
在 main.js 里
import Request from './utils/request'
Vue.prototype.$http = Request
然后就可以开开心心在 vue 单文件组件里 this.$http(各种参数).then() 的使用拉,流畅又爽
我们还需要啥技能?用 vue 写小程序
不要怀疑,山东人就是喜欢倒装句咋地
好像没啥了
直接
// 把之前的npm run dev:mp-weixin的黑窗口ctr+c退出哈先
// 然后执行
npm run build:mp-weixin
关闭当先开发者工具里的项目,重新引入 dist 文件夹下面的 build 文件夹中的 mp-weixin 文件夹,这是我们打包好的文件,引入之后,自己测试一遍,没问题后点击开发者工具的右上角上传按钮,进行上传代码,然后登录微信小程序后台把代码提交审核就行啦。