从零开始搭建SpringBoot项目(一)——开发环境搭建
从零开始搭建SpringBoot项目(二)——Swagger接口测试平台搭建
需要安装 | 下载方法 |
---|---|
HbuilderX | 自备最新版本 |
微信开发者工具 | 官网下载链接 |
本章静态资源素材 | 百度网盘下载链接,提取码:edvr |
之前两篇文章我已经把后端的基础搭建好了,为了让大家能对项目开发有更直观的感受,这次我们先从小程序前端搭建入手,通过前端的设计我们自然就能知道向后端Java项目发出什么请求,提交什么数据了,以及后端系统要查询哪些表的记录才能客户端的需求。
本篇前半部分我会详细介绍Uni-app框架以及通过几个demo让大家了解小程序前端是如何运作的,有基础的同学可以直接跳到后面看实战代码。
我们本篇将要实现小程序的登录注册页面的如下
如何申请微信开发者账号就不介绍了,大家自行百度吧。
开发微信小程序必须要用到 AppID 和 密钥 ,这两个东西可以在微信开发者平台上面获得。在网页中找到开发栏目,然后选择开发设置选项卡,在面板中你就能看到自己的小程序对应的 AppID 和 密钥 了。如果是刚注册下来的账号,密钥还没有生成,你要手动点击页面上的按钮,生成密钥字符串。如果已经生成过密钥字符串,那么默认情况,页面会隐藏密钥字符串,你只能点击重置按钮,生成新的密钥字符串了。所以强烈建议大家,获取了密钥字符串之后,最好能用文件把密钥字符串保存下来。
在左边项目栏打开刚刚创建的UNI-App项目,接着打开manifest.json文件,在里面找到微信小程序配置页面填下你自己的小程序AppID
然后选择运行微信小程序,之后将会自动启动微信开发者工具,并且让你扫码登陆
开发过微信小程序的人都应该知道,微信提供的开发语言十分不方便,而且开发页面显得繁杂,更重的是你就算学会了微信开发语言你还没办法应用在别的地方,而uni-app是一个基于VUE语法的跨平台移动端框架,会VUE的人,半天时间就能上手掌握uni-app框架。从项目结构,到页面语法,与前端的VUE工程几乎相同,我们何苦不学一门更大众化的语言呢?
uni-app 框架最让人着迷的地方在于,借助于 HBuilderX 工具,我们可以把 uni-app 项目,编译成各种类型的移动端工程。比如说我们可以把 uni-app 项目编译成微信小程序。
结构 | 用途 |
---|---|
pages目录 | 存放页面文件 |
static目录 | 存放静态文件(图片) |
App.vue文件 | 所有小程序页面都被引用到该文件运行 |
main.js文件 | 项目入口文件,用来初始化VUE对象,定义全局组件等 |
manifest.json文件 | 工程配置文件,声明应用的名称、图标、权限等 |
pages.json文件 | 页面注册文件,配置页面路径、窗口样式、标题文字等 |
uni.scss文件 | 全局样式文件 |
"pages": [
{
"path": "pages/demo/demo",
"style": {
"navigationBarTitleText": "",
"enablePullDownRefresh": false
}
},
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "uni-app"
}
}
]
<template>
<view>
<view>{{username}}</view>
<view v-for="one in tel">{{one}}</view>
<view v-if="age>=18">
<button @tap="signUp">我要报名</button>
</view>
<view>
<input type="text" v-model="address" placeholder="输入地址" />
</view>
<view>输入的内容:{{address}}</view>
</view>
</template>
<script>
export default {
data() {
return {
username: "Scott",
tel: [13312345678, 15912345678],
age: 18,
address: ""
};
},
methods:{
signUp: function() {
uni.showToast({
title: "点击了报名按钮"
})
}
}
}
</script>
<style>
</style>
因为低版本的调试基础库对uni-app支持的不够好,所以我们要先把基础库的版本设置为最新,然后再运行小程序项目,不然报基础库版本低的错误。
刚刚demo.vue文件编译运行后
具体我们实现的页面效果呢,在文章开头已经向大家展示了。
大家看过效果应该发现这个登录和注册页面稍微有点不太一样,注册和登录页面是融合在一起。所以我们就不需要分别创建登录和注册文件了。
我们先来把静态的登陆注册页面和部分JS代码给设计出来。
大家在文章开头找到图片素材的百度网盘链接进行下载,然后把里面的static文件夹和colorui拷贝到当前小程序项目中,这样就成功导入登录注册所要的各种静态资源了。
①在小程序中创建login.vue文件
②然后在 page.json 文件中把这个文件的注册顺序设置成第一位
代码(千万别忘了用逗号分隔每个注册页面)
{
"path": "pages/login/login",
"style": {
"navigationBarTitleText": "欢迎来到何壹时的博客",
"enablePullDownRefresh": false
}
},
@font-color: #333;
@desc-color: #999;
@background-color: #CC6633;
@background-color-active: #CC3333;
<style>
/*每个页面公共css */
@import "colorui/main.css";
@import "colorui/icon.css";
</style>
④编写 login.vue 文件
<template>
<view>
<view class="top-right-corner"></view>
<view class="lower-left-corner"></view>
<scroll-view scroll-y class="page">
<view class="container">
<view class="box login" :style="{'transform':login_page}">
<view class="form-content">
<view class="avtar">
<view class="pic">
<image src="/static/logo-1.png" alt="">
</view>
</view>
<view class="logo-title">登录注册页面</view>
<view class="cu-form-group">
<view class="padding flex flex-direction">
<button class="login-btn" open-type="getUserInfo" @tap="login()" >登陆</button>
</view>
</view>
<view class="btn-bottom">
还没有账户? <text @click="toSign()" class="signupbtn">注册</text>
</view>
</view>
</view>
<view class="box signup" :style="{'transform':signup_page}">
<view class="form-content">
<view class="avtar">
<view class="pic">
<image src="/static/logo-2.png" alt="">
</view>
</view>
<view>
<view class="padding flex flex-direction">
<button class="signup-btn" open-type="getUserInfo" @tap="register()">执行注册</button>
</view>
</view>
<view class="btn-bottom ">
已经有账号了? <text @click='tologin()' class="loginbtn">登陆</text>
</view>
</view>
</view>
</view>
<view class="cu-tabbar-height"></view>
</scroll-view>
</view>
</template>
<script>
export default {
data() {
return {
registerCode: '',
code:null,
login_page: '',
signup_page: ''
};
},
methods: {
toSign() { //跳转至注册页面
this.login_page = 'rotateY(180deg)';
this.signup_page = 'rotateY(0deg)';
},
tologin() { //跳转至登录页面
this.login_page = 'rotateY(0deg)';
this.signup_page = 'rotateY(-180deg)';
}
}
};
</script>
<style lang="scss">;
.page {
height: 100vh;
}
.top-right-corner {
position: fixed;
top: -280rpx;
right: -280rpx;
width: 600rpx;
height: 550rpx;
background-color: #FFFFFF;
border: 100rpx solid #ffdddf;
border-radius: 100%;
z-index: 1;
}
.lower-left-corner {
position: fixed;
bottom: -450rpx;
left: -200rpx;
width: 700rpx;
height: 680rpx;
background-color: #FFFFFF;
border: 100rpx solid #c7e1fa;
transform: rotate(-45deg);
z-index: 1;
}
.logo-title{
position: absolute;
font-size: 40upx;
font-weight: bold;
text-align: center;
margin-top: 5%;
}
.btn-box {
margin-top: 50rpx;
display: flex;
justify-content: center;
align-items: center;
height: 100rpx;
background-color: #496df4;
border-radius: 40rpx;
color: #FFFFFF;
font-size: 30rpx;
box-shadow: 0rpx 20rpx 40rpx #859df4;
}
.login-btn{
width: 60%;
position: absolute;
left: 20%;
background-color: #CC6633;
color: #fff;
box-sizing: border-box;
background-color: #496df4;
border-radius: 40rpx;
box-shadow: 0rpx 20rpx 40rpx #859df4;
&:active{
background-color: #859df4;
}
}
.signup-btn{
width: 60%;
position: absolute;
left: 20%;
color: #fff;
background-color: #496df4;
border-radius: 40rpx;
box-shadow: 0rpx 20rpx 40rpx #859df4;
box-sizing: border-box;
&:active{
background-color: #859df4;
}
}
.btn-bottom{
position: relative;
height: 20upx;
width: 100%;
text-align: center;
}
.container {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 20rem;
height: 34rem;
perspective: 1500px;
-webkit-perspective: 1500px;
-moz-perspective: 1500px;
}
.box {
position: absolute;
top: 0;
left: 0;
width: 20rem;
height: 30rem;
border-radius: 10px;
cursor: pointer;
backface-visibility: hidden;
transition: all 0.5s;
user-select: none;
}
.signup {
transform: rotateY(-180deg); //解決切换闪烁问题
}
.container .form-content {
position: relative;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
flex-wrap: wrap;
box-shadow: 0 0 1upx #3399ff;
border-radius: 30upx;
background-color: #fff;
}
.container .form-content .avtar {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
}
.container .form-content .avtar .pic {
position: relative;
width: 450upx;
height: 300upx;
overflow: hidden;
}
.container .form-content .avtar .pic image {
position: absolute;
width: 100%;
height: 100%;
}
.register-code{
border: 1upx solid #e0e0e0;
font-size: 34upx;
color: #333;
text-align: center;
background-color: #f5f5f5;
border-radius: 10upx;
margin-bottom: 30upx;
height: 80upx;
padding: 0 10upx;
margin-left: 20%;
margin-right: 20%;
}
.register-desc{
width: 70%;
margin-left: auto;
margin-right: auto;
color: #999;
font-size: 28rpx;
line-height: 1.5;
}
.loginbtn,
.signupbtn {
color: #0081ff;
}
</style>
首先我们可以从微信APP上面获得用户临时授权字符串(Code),然后把这个字符串传递给后端Java系统,让Java系统拿着AppId、密钥和Code,提交给微信平台换取OpenId
String url = "https://api.weixin.qq.com/sns/jscode2session";
HashMap map = new HashMap();
map.put("appid", appId);
map.put("secret", appSecret);
map.put("js_code", code);
map.put("grant_type", "authorization_code");
String response = HttpUtil.post(url, map);
JSONObject json = JSONUtil.parseObj(response);
String openId = json.getStr("openid");
在 uni-app 框架中,包含了原生微信小程序的 wx 对象,我们可以像写原生微信小程序代码一样,通过 wx 对象调用各种方法。但是我更推荐大家使用 uni 对象,因为这个对象是跨平台的,我们调用 uni 对象中的方法,HBuilderX 在编译代码的时候,会把 uni 对象翻译成目标平台的对象,比如微信平台就是 wx 对象,支付宝平台就是 my 对象,所以 uni 对象的跨平台性更好,而且调用更加简单,强烈推荐大家使用。
使用uni对象可以轻松获取微信小程序的临时授权字符串,这个临时授权字符串是有时间限定的,默认有效期是5分钟。如果过期,就无法换取 OpenId 了。
uni.login({
provider: 'weixin',
success: function (resp) {
console.log(resp.code);
}
});
注意: 微信小程序端,在用户未授权过的情况下调用此接口,不会出现授权弹窗,会直接进入 fail 回调(详见《微信小程序公告》)。在用户已授权的情况下调用此接口,可成功获取用户信息。
uni.login({
provider: 'weixin',
success: function (resp) {
let code = resp.code;
// 获取用户信息
uni.getUserInfo({
provider: 'weixin',
success: function (resp) {
let nickName = resp.userInfo.nickName;
let avatarUrl = resp.userInfo.avatarUrl;
}
});
}
});
示例2(推荐此种方式)
uni.login({
provider: 'weixin',
success: function (resp) {
let code = resp.code;
// 获取用户信息
uni.getUserProfile({
desc: '获取用户信息',
success: function (resp) {
let nickName = resp.userInfo.nickName;
let avatarUrl = resp.userInfo.avatarUrl;
}
});
}
});
注意此种获取用户信息的方式在真机调试上面可以使用,但是在小程序开发工具的微信模拟器上无法使用。所以大家运行用户注册的时候,必须用真机调试才行。
通过刚刚的了解,我们知道了uni-app提供了获取临时授权的方法,接下来我们就利用这个方法来编写我们的代码吧。
这里我会稍微有点超前的讲解,看不懂没关系,本来登录注册方法应该放在下一章和后端交互一起讲的,但想着刚刚介绍完获取临时授权和微信基本信息的方法那就趁热打铁吧!下一章将会详细讲解这部分代码的!
将以下这部分代码加到< script > < /script >的methods方法里吧
login: function() {
let that = this;
uni.login({
provider: 'weixin',
success: function(resp) {
let code = resp.code;
let token = uni.getStorageSync('token');
that.ajax(that.url.login, 'POST', { code: code }, function(resp) {
let permission = resp.data.permission;
uni.setStorageSync('permission', permission);
//跳转到登陆页面
uni.switchTab({
url: '../index/index'
});
});
},
fail: function(e) {
uni.showToast({
icon: 'none',
title: '执行异常'
});
}
});
},
register: function() {
let that = this;
uni.login({
provider: 'weixin',
success: function(resp) {
let code = resp.code;
that.code=code
}
});
uni.getUserProfile({
desc: '获取用户信息',
success: function(resp) {
let nickName = resp.userInfo.nickName;
let avatarUrl = resp.userInfo.avatarUrl;
// console.log(nickName);
// console.log(avatarUrl);
let data = {
code: that.code,
nickname: nickName,
photo: avatarUrl,
registerCode: that.registerCode
};
//下面这里封装了Ajax,下一章会讲解的
that.ajax(that.url.register, 'POST', data, function(resp) {
let permission = resp.data.permission;
let token = resp.data.token;
uni.setStorageSync('token', token);
uni.setStorageSync('permission', permission);
//跳转至主页
uni.switchTab({
url: '../index/index'
});
});
}
});
}
}
好了本次分享到此结束了!谢谢大家阅读!
下一章将会介绍小程序如何跟后端交互,以及如何将用户数据经过后端存储至MySQL!
之后会慢慢会恢复更新了,希望大家继续关注,还有更多优质博客在来的路上!!