UNIAPP实战项目笔记62 第三方快捷登录,微信登录,QQ登录,微博登录前后端实现
总体思路
用户点击了快捷方式登录,信息是否要存储在数据库中?肯定的
后端:
1.新增接口
2.新增字段
前端
1.点击哪一个快捷登录方式
2.需要给后端传递数据
HBulider X设置
后端数据表
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`userName` varchar(255) DEFAULT NULL,
`userPwd` varchar(255) DEFAULT NULL,
`phone` varchar(255) DEFAULT NULL,
`imgUrl` varchar(255) DEFAULT NULL,
`nickName` varchar(255) DEFAULT NULL,
`token` varchar(255) DEFAULT NULL,
`provider` varchar(255) DEFAULT NULL,
`openid` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
案例图片
第三方登录接口文档
1.2 URL
地址/api/loginother
1.3 支持格式
JSON
1.4 HTTP请求方法
POST
1.5 请求参数
参数 | 必选 | 类型 | 说明 |
---|---|---|---|
povider | 是 | string | 登录方式 |
openid | 是 | string | 身份 |
nikename | 是 | string | 用户昵称 |
avatarUrl | 是 | string | 用户头像 |
1.6返回字段
返回字段 | 字段类型 | 说明 |
---|---|---|
code | string | 返回结果状态 0:正常; |
data | object | 首页数据 |
1.7 接口示例
{
"data":{
token:"",
avatarUrl:"",
...用户信息
}
}
后端接口文件 index.js
var express = require('express');
var router = express.Router();
var connection = require('../db/sql.js');
var user = require('../db/UserSql.js');
// 验证码
let code = '';
// 接入短信的sdk
// var QcloudSms = require('qcloudsms_js');
//设置跨域访问(设置在所有的请求前面即可)
router.all("*", function (req, res, next) {
//设置允许跨域的域名,*代表允许任意域名跨域
res.header("Access-Control-Allow-Origin", "*");
//允许的header类型
res.header("Access-Control-Allow-Headers", "content-type");
//跨域允许的请求方式
// res.header("Access-Control-Allow-Methods", "DELETE,PUT,POST,GET,OPTIONS");
res.header("Access-Control-Allow-Methods", "*");
res.header("Content-Type", "application/json;chartset=utf-8");
// if (req.method == 'OPTIONS')
// res.sendStatus(200); //让options尝试请求快速结束
// else
next();
});
/* GET home page. */
router.get('/', function(req, res, next) {
res.send({
data:{
aaa:'1111'
}
});
// res.render('index', { title: 'Express' });
});
/* 测试token数据. */
router.post('/api/ceshi', function(req, res, next) {
console.log(111);
res.send({
data:{
aaa:'1111'
}
});
});
/* 第三方登录 */
router.post('/api/loginother', function(req, res, next) {
// 前端给后端的数据
let params = {
provider:req.body.provider,//登录方式
openid:req.body.openid,//用户身份id
nickName:req.body.nickName,//用户昵称
avataUrl:req.body.avataUrl//用户头像
};
console.log(params);
// 查询数据库中用户是否存在
connection.query(user.queryUserName(params),function(error,results,fields){
if(results.length > 0){
// 数据库中存在 直接读取
connection.query( user.queryUserName( params ), function(err2, res2) {
res.send({
data:res2[0]
});
});
}else{
// 数据库中不存在 存储 -> 读取
connection.query( user.insertData( params ), function(err1,res1) {
connection.query( user.queryUserName( params ), function(err2, res2) {
res.send({
data:res2[0]
});
});
});
}
})
});
/* 注册->增加一条数据. */
router.post('/api/addUser', function(req, res, next) {
// 前端给后端的数据
let params = {
userName:req.body.userName,
userCode:req.body.code
};
if( params.userCode == code ){
connection.query( user.insertData( params ),function(error,results, fields){
// 再去查询手机号是否存在,用于注册成功后直接登录
connection.query(user.queryUserName(params),function(er,result){
if(results.length > 0){
res.send({
data:{
success:true,
msg:'注册成功',
data:result[0]
}
});
}
});
// res.send({
// data:{
// success:true,
// msg:'注册成功'
// }
// });
});
}
});
/* 发送验证码 */
router.post('/api/code', function(req, res, next) {
// 前端给后端的数据
let params = {
userName : req.body.userName
}
// 短信SDK 可以使用阿里云或腾讯云的,具体接入方式以官方NodeJS代码案例
// ....
// 阿里云 官方代码 https://help.aliyun.com/document_detail/112185.html
// 腾讯云 官方代码 https://cloud.tencent.com/developer/article/1987501
// ....
// ....
var paramss = [ Math.floor( Math.random()*(9999-1000)+1000 ) ] // 要发送的验证码
// 模拟以获取到验证码
code = paramss[0];
console.log(code);
// 模拟成功返回验证码
res.send({
data:{
success:true,
code : paramss[0]
}
})
})
/* 注册验证手机号是否存在 */
router.post('/api/registered', function(req, res, next) {
// 前端给后端的数据
let params = {
userName : req.body.phone
}
// 查询手机号是否存在
connection.query(user.queryUserName(params),function(error,results,fields){
if(results.length > 0){
res.send({
data:{
success:false,
msg:"手机号已经存在!"
}
});
}else{
res.send({
data:{
success:true
}
});
}
})
});
/* 用户登录 */
router.post('/api/login', function(req, res, next) {
// 前端给后端的数据
let params = {
userName : req.body.userName,
userPwd : req.body.userPwd
}
// 查询用户名或手机号是否存在
connection.query(user.queryUserName(params),function(error,results,fields){
if(results.length > 0){
connection.query(user.queryUserPwd(params),function(erro,result){
if(result.length > 0){
res.send({
data:{
success:true,
msg:"登录成功!",
data:result[0]
}
});
}else{
res.send({
data:{
success:false,
msg:"密码不正确!"
}
});
}
})
}else{
res.send({
data:{
success:false,
msg:"用户名或手机号不存在!"
}
});
}
})
});
/* GET databases goods Detail. */
router.get('/api/goods/id', function(req, res, next) {
let id = req.query.id;
connection.query("select * from goods_search where id='"+id+"'",function(error,result,fields){
if(error) throw error;
res.send({
code:"0",
data:result
})
})
});
/* GET List Page */
router.get('/api/goods/list', function(req, res, next) {
res.send({
code:0,
name:"家居家纺",
data:[
{
id:1,
name:"家纺",
data:[
{
name:"家纺",
list:[
{
id:1,
name:"毛巾/浴巾",
imgUrl:"/static/logo.png"
},
{
id:2,
name:"枕头",
imgUrl:"/static/logo.png"
}
]
},
{
name:"生活用品",
list:[
{
id:1,
name:"浴室用品",
imgUrl:"/static/logo.png"
},
{
id:2,
name:"洗晒",
imgUrl:"/static/logo.png"
}
]
}
]
},
{
id:2,
name:"女装",
data:[
{
name:"裙装",
list:[
{
id:1,
name:"连衣裙",
imgUrl:"/static/logo.png"
},
{
id:2,
name:"半身裙",
imgUrl:"/static/logo.png"
}
]
},
{
name:"上衣",
list:[
{
id:1,
name:"T恤",
imgUrl:"/static/logo.png"
},
{
id:2,
name:"衬衫",
imgUrl:"/static/logo.png"
}
]
}
]
}
]
});
});
/* GET databases goods. */
router.get('/api/goods/search', function(req, res, next) {
/*
desc 降序 asc 升序
*/
// 获取对象的key
let [goodsName,orderName] = Object.keys(req.query);
// name参数的值
let name = req.query.name;
// orderName的key值
let order = req.query[orderName];
let sql = "select * from goods_search";
if(!(name == undefined || orderName == undefined || order == undefined)){
sql = "select * from goods_search where name like '%"+name+"%' order by "+orderName+" "+order;
}
connection.query(sql,function(error,results,fields){
res.send({
code:"0",
data:results
});
})
});
/* 首页第一次触底的数据 */
router.get('/api/index_list/1/data/2', function(req, res, next) {
res.send({
code:"0",
data:[
{
type:"commodityList",
data:[
{
id:1,
imgUrl:"../../static/logo.png",
name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
pprice:"299",
oprice:"659",
discount:"5.2"
},
{
id:2,
imgUrl:"../../static/logo.png",
name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
pprice:"299",
oprice:"659",
discount:"5.2"
},{
id:3,
imgUrl:"../../static/logo.png",
name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
pprice:"299",
oprice:"659",
discount:"5.2"
},
{
id:4,
imgUrl:"../../static/logo.png",
name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
pprice:"299",
oprice:"659",
discount:"5.2"
},
]
},
]
});
});
/* 运动户外第二次触底的数据 */
router.get('/api/index_list/2/data/3', function(req, res, next) {
res.send({
code:"0",
data:[
{
type:"commodityList",
data:[
{
id:1,
imgUrl:"../../static/logo.png",
name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
pprice:"299",
oprice:"659",
discount:"5.2"
},
{
id:2,
imgUrl:"../../static/logo.png",
name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
pprice:"299",
oprice:"659",
discount:"5.2"
},{
id:3,
imgUrl:"../../static/logo.png",
name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
pprice:"299",
oprice:"659",
discount:"5.2"
},
{
id:4,
imgUrl:"../../static/logo.png",
name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
pprice:"299",
oprice:"659",
discount:"5.2"
},
]
},
]
});
});
/* 运动户外第一次触底的数据 */
router.get('/api/index_list/2/data/2', function(req, res, next) {
res.send({
code:"0",
data:[
{
type:"commodityList",
data:[
{
id:1,
imgUrl:"../../static/logo.png",
name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
pprice:"299",
oprice:"659",
discount:"5.2"
},
{
id:2,
imgUrl:"../../static/logo.png",
name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
pprice:"299",
oprice:"659",
discount:"5.2"
},{
id:3,
imgUrl:"../../static/logo.png",
name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
pprice:"299",
oprice:"659",
discount:"5.2"
},
{
id:4,
imgUrl:"../../static/logo.png",
name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
pprice:"299",
oprice:"659",
discount:"5.2"
},
]
},
]
});
});
/* 运动户外第一次加载的数据 */
router.get('/api/index_list/2/data/1', function(req, res, next) {
res.send({
code:"0",
data:[
{
type:"bannerList",
imgUrl:"../../static/img/b3.jpg",
},
{
type:"iconsList",
data:[
{imgUrl:"../../static/logo.png",name:"运动户外"},
{imgUrl:"../../static/logo.png",name:"运动户外"},
{imgUrl:"../../static/logo.png",name:"运动户外"},
{imgUrl:"../../static/logo.png",name:"运动户外"},
{imgUrl:"../../static/logo.png",name:"运动户外"},
{imgUrl:"../../static/logo.png",name:"运动户外"},
{imgUrl:"../../static/logo.png",name:"运动户外"},
{imgUrl:"../../static/logo.png",name:"运动户外"}
]
},
{
type:"hotList",
data:[
{
id:1,
imgUrl:"../../static/logo.png",
name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
pprice:"299",
oprice:"659",
discount:"5.2"
},
{
id:2,
imgUrl:"../../static/logo.png",
name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
pprice:"299",
oprice:"659",
discount:"5.2"
},{
id:3,
imgUrl:"../../static/logo.png",
name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
pprice:"299",
oprice:"659",
discount:"5.2"
}
]
},
{
type:"shopList",
data:[
{
bigUrl:"../../static/img/b3.jpg",
data:[
{
id:1,
imgUrl:"../../static/logo.png",
name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
pprice:"299",
oprice:"659",
discount:"5.2"
},
{
id:2,
imgUrl:"../../static/logo.png",
name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
pprice:"299",
oprice:"659",
discount:"5.2"
},{
id:3,
imgUrl:"../../static/logo.png",
name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
pprice:"299",
oprice:"659",
discount:"5.2"
},
{
id:4,
imgUrl:"../../static/logo.png",
name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
pprice:"299",
oprice:"659",
discount:"5.2"
}
]
}
],
},
{
type:"commodityList",
data:[
{
id:1,
imgUrl:"../../static/logo.png",
name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
pprice:"299",
oprice:"659",
discount:"5.2"
},
{
id:2,
imgUrl:"../../static/logo.png",
name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
pprice:"299",
oprice:"659",
discount:"5.2"
},{
id:3,
imgUrl:"../../static/logo.png",
name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
pprice:"299",
oprice:"659",
discount:"5.2"
},
{
id:4,
imgUrl:"../../static/logo.png",
name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
pprice:"299",
oprice:"659",
discount:"5.2"
},
]
},
]
});
});
/* 服饰内衣第一次加载的数据 */
router.get('/api/index_list/3/data/1', function(req, res, next) {
res.send({
code:"0",
data:[
{
type:"bannerList",
imgUrl:"../../static/img/b3.jpg",
},
{
type:"iconsList",
data:[
{imgUrl:"../../static/logo.png",name:"服饰内衣"},
{imgUrl:"../../static/logo.png",name:"服饰内衣"},
{imgUrl:"../../static/logo.png",name:"服饰内衣"},
{imgUrl:"../../static/logo.png",name:"服饰内衣"},
{imgUrl:"../../static/logo.png",name:"服饰内衣"},
{imgUrl:"../../static/logo.png",name:"服饰内衣"},
{imgUrl:"../../static/logo.png",name:"服饰内衣"},
{imgUrl:"../../static/logo.png",name:"服饰内衣"}
]
},
{
type:"hotList",
data:[
{
id:1,
imgUrl:"../../static/logo.png",
name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
pprice:"299",
oprice:"659",
discount:"5.2"
},
{
id:2,
imgUrl:"../../static/logo.png",
name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
pprice:"299",
oprice:"659",
discount:"5.2"
},{
id:3,
imgUrl:"../../static/logo.png",
name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
pprice:"299",
oprice:"659",
discount:"5.2"
}
]
},
{
type:"shopList",
data:[
{
bigUrl:"../../static/img/b3.jpg",
data:[
{
id:1,
imgUrl:"../../static/logo.png",
name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
pprice:"299",
oprice:"659",
discount:"5.2"
},
{
id:2,
imgUrl:"../../static/logo.png",
name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
pprice:"299",
oprice:"659",
discount:"5.2"
},{
id:3,
imgUrl:"../../static/logo.png",
name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
pprice:"299",
oprice:"659",
discount:"5.2"
},
{
id:4,
imgUrl:"../../static/logo.png",
name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
pprice:"299",
oprice:"659",
discount:"5.2"
}
]
}
],
},
{
type:"commodityList",
data:[
{
id:1,
imgUrl:"../../static/logo.png",
name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
pprice:"299",
oprice:"659",
discount:"5.2"
},
{
id:2,
imgUrl:"../../static/logo.png",
name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
pprice:"299",
oprice:"659",
discount:"5.2"
},{
id:3,
imgUrl:"../../static/logo.png",
name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
pprice:"299",
oprice:"659",
discount:"5.2"
},
{
id:4,
imgUrl:"../../static/logo.png",
name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
pprice:"299",
oprice:"659",
discount:"5.2"
},
]
},
]
});
});
/* 首页推荐数据 */
router.get('/api/index_list/data', function(req, res, next) {
res.send({
"code":0,
"data":{
topBar:[
{id:1,name:'推荐'},
{id:2,name:'运动户外'},
{id:3,name:'服饰内衣'},
{id:4,name:'鞋靴箱包'},
{id:5,name:'美妆个护'},
{id:6,name:'家居数码'},
{id:7,name:'食品母婴'}
],
data:[
{
type:"swiperList",
data:[
{imgUrl:'/static/img/b3.jpg'},
{imgUrl:'/static/img/b3.jpg'},
{imgUrl:'/static/img/b3.jpg'}
]
},{
type:"recommendList",
data:[
{
bigUrl:"../../static/img/b3.jpg",
data:[
{imgUrl:'../../static/logo.png'},
{imgUrl:'../../static/logo.png'},
{imgUrl:'../../static/logo.png'}
]
},{
bigUrl:"../../static/img/b3.jpg",
data:[
{imgUrl:'../../static/logo.png'},
{imgUrl:'../../static/logo.png'},
{imgUrl:'../../static/logo.png'}
]
}
]
},{
type:"commodityList",
data:[
{
id:1,
imgUrl:"../../static/logo.png",
name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
pprice:"299",
oprice:"659",
discount:"5.2"
},
{
id:2,
imgUrl:"../../static/logo.png",
name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
pprice:"299",
oprice:"659",
discount:"5.2"
},{
id:3,
imgUrl:"../../static/logo.png",
name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
pprice:"299",
oprice:"659",
discount:"5.2"
},
{
id:4,
imgUrl:"../../static/logo.png",
name:"迪奥绒毛大衣,今年必抢,错过瞬时不爽了,爆款疯狂销售",
pprice:"299",
oprice:"659",
discount:"5.2"
},
]
},
]
}
})
});
module.exports = router;
后端文件 UserSql.js
let User = {
// 查询用户名或手机号
queryUserName( param ){
if( param.userName ){
return "select * from user where userName = '"+param.userName+"' or phone ='"+param.userName+"'";
}else{
// 第三方登录
return "select * from user where provider = '"+param.provider+"' or openid ='"+param.openid+"'";
}
},
// 查询用户名和密码
queryUserPwd( param ){
return "select * from user where (userName = '"+param.userName+"' or phone ='"+param.userName+"') and userPwd ='"+param.userPwd+"'";
},
// 增加一条用户数据
insertData( param ){
let userName = param.userName || param.openid;
const jwt = require('jsonwebtoken');// 生成token秘钥
let payload = {name:userName};//用户名
let secret = 'alalal';//自定义口令
let token = jwt.sign(payload,secret);
let nickName = param.nickName || "默认昵称";
let avatarUrl = param.avatarUrl || "../../static/logo.png";
return "insert into user (userName,userPwd,phone,imgUrl,nickName,token,provider,openid) values ('','a1a1a1','"+param.userName+"','"+avatarUrl+"','"+nickName+"','"+token+"','"+param.provider+"','"+param.openid+"')";
}
}
exports = module.exports = User;
前端文件 login-other.vue
<template>
<view class="login-other">
<view class="other-text">
<view class="">用以下方式登录</view>
</view>
<view class="other">
<view class="other-item" @tap="loginOther('weixin')">
<image src="../../static/img/wx.png" mode=""></image>
<view class="">
微信登录
</view>
</view>
<view class="other-item" @tap="loginOther('sinaweibo')">
<image src="../../static/img/wb.png" mode=""></image>
<view class="">
微博登录
</view>
</view>
<view class="other-item" @tap="loginOther('qq')">
<image src="../../static/img/qq.png" mode=""></image>
<view class="">
QQ登录
</view>
</view>
</view>
</view>
</template>
<script>
import $http from '@/common/api/request.js';
import {mapMutations} from 'vuex';
export default {
methods:{
...mapMutations(['login']),
loginOther(mode){
uni.login({
provider:mode,
success: (res) => {
console.log(res);
// 从res中获取openid
// let openid = res.authResult.openid;
uni.getUserInfo({
provider:mode,
success: (re) => {
console.log(re);
let provider = mode;
// openid用户身份
let openid = res.userInfo.openid || res.userInfo.openId;
let nickName = res.userInfo.nickName;
let avatarUrl = res.userInfo.avatarUrl;
$http.request({
url:'/loginother',
method:"POST",
data:{
provider,
openid,
nickName,
avatarUrl
}
}).then((res)=>{
// 保存用户信息
this.login(res);
setTimeout(()=>{
uni.navigateBack();
},1000)
}).catch(()=>{
uni.showToast({
title:'请求失败',
icon:'none'
})
})
}
})
}
})
}
},
name:"login",
data() {
return {
};
}
}
</script>
<style lang="scss">
// 其他登录方式
.login-other{
padding: 100rpx 0;
}
.other-text{
display: flex;
padding: 50rpx 0;
}
.other-text:before{
flex:1;
content: "";
height: 2rpx;
background-color: #ccc;
}
.other-text::after{
flex:1;
content: "";
height: 2rpx;
background-color: #ccc;
}
.other{
display: flex;
justify-content: space-around;
}
.other-item{
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.other-item image{
width: 80rpx;
height: 80rpx;
}
// 其他登录方式end
</style>
前端文件 login.vue
<template>
<view class="login">
<swiper vertical="true" style="height: 100vh;">
<swiper-item>
<scroll-view>
<view class="login-tel">
<view class="tel-main">
<view class="close" @tap="goBack">
<image class="close-img" src="../../static/img/close-bold.png" mode=""></image>
</view>
<view class="logo">
<image class="logo-img" src="../../static/logo.png" mode=""></image>
</view>
<view class="tel" @tap="goLoginTel">手机号注册</view>
<LoginOther></LoginOther>
<view class="login-go">
<view class="">已有账号,去登录</view>
<image src="../../static/img/arrow-down.png" mode=""></image>
</view>
</view>
</view>
</scroll-view>
</swiper-item>
<swiper-item>
<scroll-view>
<view class="login-tel">
<view class="tel-main">
<view class="close close-center">
<view class="" @tap="goBack">
<image class="close-img" src="../../static/img/close-bold.png" mode=""></image>
</view>
<view class="login-go">
<image class="close-img" src="../../static/img/up.png" mode=""></image>
<view class="">没账号,去注册</view>
</view>
<view class=""></view>
</view>
<view class="login-form">
<view class="login-user">
<text class='user-text'>账号</text>
<input type="text" v-model="userName" value="" placeholder="请输入手机号/昵称"/>
</view>
<view class="login-user">
<text class='user-text'>密码</text>
<input type="safe-password" v-model="userPwd" value="" placeholder="6-16位字符"/>
</view>
</view>
<view class="login-quick">
<view class="">忘记密码</view>
<view class="">免密登录</view>
</view>
<view class="tel" @tap="submit">登录</view>
<view class="reminder">温馨提示,您可以选择免密登录,更加方便</view>
<LoginOther></LoginOther>
</view>
</view>
</scroll-view>
</swiper-item>
</swiper>
</view>
</template>
<script>
import $http from '@/common/api/request.js'
import LoginOther from '@/components/login/login-other.vue'
import {mapMutations} from 'vuex'
export default {
data() {
return {
userName:"",
userPwd:"",
rules:{
userName:{
rule:/\S/,
msg:"账号不能为空 "
},
userPwd:{
rule:/^[0-9a-zA-Z]{6,16}$/,
msg:"密码应该为6-16位字符"
}
}
};
},
components:{
LoginOther
},
methods:{
...mapMutations(['login']),
goBack(){
uni.navigateBack();
},
submit(){
if( !this.validate('userName') ) return ;
if( !this.validate('userPwd') ) return ;
uni.showLoading({
title:"登录中..."
});
// setTimeout(()=>{
// uni.hideLoading();
// uni.navigateBack();
// },2000)
$http.request({
url:'/login',
method:"POST",
data:{
userName: this.userName,
userPwd : this.userPwd
}
}).then((res)=>{
if(res.success){
// 保存用户信息
this.login(res.data);
console.log(res.data);
uni.showToast({
title:res.msg,
icon:"none"
})
uni.hideLoading();
setTimeout(()=>{
uni.navigateBack();
},1000)
}else{
uni.showToast({
title:res.msg,
icon:"none"
})
}
}).catch(()=>{
uni.showToast({
title:'请求失败',
icon:'none'
})
})
},
// 判断验证是否符合要求
validate(key){
let bool = true;
if( !this.rules[key].rule.test(this[key]) ){
uni.showToast({
title:this.rules[key].msg,
icon:'none'
});
bool = false;
return false;
}
return bool;
},
// 进入手机号注册页面
goLoginTel(){
uni.navigateTo({
url:"/pages/login-tel/login-tel"
})
}
}
}
</script>
<style lang="scss">
.login-tel{
width: 100vw;
height: 100vh;
}
.tel-main{
padding: 0 20rpx;
}
.close{
padding: 120rpx 0;
}
.close-img{
width: 60rpx;
height: 60rpx;
}
.logo{
padding: 0 100rpx;
padding-bottom: 100rpx;
display: flex;
justify-content: center;
}
.logo-img{
width: 200rpx;
height: 200rpx;
}
.tel{
width: 100%;
height: 80rpx;
line-height: 80rpx;
text-align: center;
color: #fff;
background-color: #40bde8;
border-radius: 40rpx;
}
.login-go{
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.login-go image{
width: 60rpx;
height: 60rpx;
}
// 第二屏
.close-center{
display: flex;
}
.close-center >view{
flex: 1;
}
.login-form{
padding-top: 100rpx;
}
.login-user{
font-size: 40rpx;
padding: 10rpx 0 ;
display: flex;
align-items: center;
border-bottom: 2rpx solid #f7f7f7;
}
.user-text{
padding-right: 10rpx;
}
.login-quick{
display: flex;
padding: 20rpx 0;
justify-content: space-between;
}
.reminder{
color: #ccc;
font-size: 32rpx;
padding: 20rpx 0;
text-align: center;
}
</style>
目录结构
前端目录结构
-
manifest.json 配置文件: appid、logo…
-
pages.json 配置文件: 导航、 tabbar、 路由
-
main.js vue初始化入口文件
-
App.vue 全局配置:样式、全局监视
-
static 静态资源:图片、字体图标
-
page 页面
- index
- index.vue
- list
- list.vue
- my
- my.vue
- my-config
- my-config.vue
- my-config
- my-config.vue
- my-add-path
- my-add-path.vue
- my-path-list
- my-path-list.vue
- search
- search.vue
- search-list
- search-list.vue
- shopcart
- shopcart.vue
- details
- details.vue
- my-order
- my-order.vue
- confirm-order
- confirm-order.vue
- payment
- payment.vue
- payment-success
- payment-success.vue
- login
- login.vue
- login-tel
login-tel.vue
- login-code
login-code.vue
- index
-
components 组件
- index
- Banner.vue
- Hot.vue
- Icons.vue
- indexSwiper.vue
- Recommend.vue
- Shop.vue
Tabbar.vue
- common
- Card.vue
- Commondity.vue
- CommondityList.vue
- Line.vue
- ShopList.vue
- order
- order-list.vue
- uni
- uni-number-box
- uni-number-box.vue
- uni-icons
- uni-icons.vue
- uni-nav-bar
- uni-nav-bar.vue
- mpvue-citypicker
- mpvueCityPicker.vue
- uni-number-box
- index
-
common 公共文件:全局css文件 || 全局js文件
- api
- request.js
- common.css
- uni.css
- api
-
store vuex状态机文件
- modules
- cart.js
- path.js
- user.js
- index.js
- modules