注意点

  • assets 文件夹:组件共用的静态资源
  • CSS 中可以写 @(src别名) ==> ~@
  • token 令牌需要持久化存储 ==> 本地存储
  • 导航守卫
    • 用户已经登录了,就不能再回到登录页,必须退出登录。
    • 用户没登录,就不能访问 购物车 页面。
  • 登录成功后,每个组件都需要获取相应用户的信息,该怎么做?

相关接口

//注册
//获取验证码  地址:/api/user/passport/sendCode/{phone}  请求方式 get
export const reqGetCode = (phone) => requests({url:`/user/passport/sendCode/${phone}`,method: "get"
});//注册 地址:/api/user/passport/register 请求方式 post  参数 :phone code password
export const reqUserRegister = (data) => requests({url:'/user/passport/register',method: "post",data
});//登录   地址:/api/user/passport/login 请求方式 post  参数 :phone  password
export const reqUserLogin = (data)=>requests({url:'/user/passport/login',data,method:'post'
});//登录成功后,通过 token 令牌,向服务器获取用户数据  地址:/api/user/passport/auth/getUserInfo 请求方式 get
export const reqUserInfo = () => requests({url:'/user/passport/auth/getUserInfo',method:'get'
});//退出登录  地址:/api/user/passport/logout 请求方式 get
export const reqLogout = ()=> requests({url:'/user/passport/logout',method:'get'
});

store/user/index.js

//引入请求
import { reqGetCode, reqUserRegister, reqUserLogin, reqUserInfo,reqLogout } from "@/api";
import { setToken, getToken, removeToken } from "@/utils/token";//登录注册的仓库
const state = {code: '',token: getToken(),userInfo: {},
};
const mutations = {GETCODE(state, data) {state.code = data;},USERLOGIN(state, data) {state.token = data;},GETUSERINFO(state, data) {state.userInfo = data;},//退出登录,清除数据(仓库和本地)CLEAR(state, data){state.token = '';state.userInfo = {};removeToken();}
};
const actions = {//获取验证码async getCode({ commit }, phone) {let result = await reqGetCode(phone);if (result.code == 200) {commit("GETCODE", result.data)return 'ok'} else {return Promise.reject(new Error('faile'))}},//用户注册async userRegister({ commit }, user) {let result = await reqUserRegister(user);if (result.code == 200) {return 'ok';} else {return Promise.reject(new Error('faile'))}},//用户登录async userLogin({ commit }, data) {let result = await reqUserLogin(data);if (result.code == 200) {//token:令牌,用户的唯一标识commit("USERLOGIN", result.data.token);//持久化存储 token ==> 本地存储setToken(result.data.token)return 'ok'} else {return Promise.reject(new Error('faile'));}},//用户登录成功,通过 token 获取用户信息async getUserInfo({ commit }) {let result = await reqUserInfo();if (result.code == 200) {//提交用户信息commit("GETUSERINFO", result.data);return 'ok';}else{return Promise.reject(new Error('faile'));}},//退出登录async userLogout({commit}){//向服务器发请求,通知服务器清除 tokenlet result = await reqLogout();if(result.code == 200){//还需清除本地记录commit("CLEAR");return 'ok';}else{return Promise.reject(new Error('faile'));}}};
const getters = {};
export default {state,mutations,actions,getters,
}

utils/token.js

//存储token
export const setToken = (token) => {localStorage.setItem("TOKEN",token)
}//获取token
export const getToken = () =>{return localStorage.getItem("TOKEN")
}//清除token
export const removeToken = () =>{return localStorage.removeItem("TOKEN")
}

Header.vue

<template>
......
//当 userName 不存在,说明没登录
<p v-if="!userName"><span>请</span><!-- 声明式导航 --><router-link to="/login">登录</router-link><router-link to="register" class="register">免费注册</router-link>
</p>
//当处于登录时,动态展示用户名
<p v-else><a>{{ userName }}</a><a class="register" @click="logout">退出登录</a>
</p>
......
</template><script>
export default {......methods: {//退出登录async logout() {try {//如果退出登录成功await this.$store.dispatch("userLogout");//回到首页this.$router.push('/home');} catch (error) {alert(error.message);}},},computed: {//用户名信息userName() {return this.$store.state.user.userInfo.name;},},
};
</script>

Login.vue

<template><div class="login-container"><!-- 登录 --><div class="login-wrap"><div class="login"><div class="loginform"><ul class="tab clearFix"><li><a href="##" style="border-right: 0">扫描登录</a></li><li><a href="##" class="current">账户登录</a></li></ul><div class="content"><form><div class="input-text clearFix"><span></span><input type="text" placeholder="邮箱/用户名/手机号" v-model="phone" /></div><div class="input-text clearFix"><span class="pwd"></span><input type="text" placeholder="请输入密码" v-model="password" /></div><div class="setting clearFix"><label class="checkbox inline"><input name="m1" type="checkbox" value="2" checked="" />自动登录</label><span class="forget">忘记密码?</span></div><button class="btn" @click="userLogin">登&nbsp;&nbsp;录</button></form><div class="call clearFix"><ul><li><img src="./images/qq.png" alt="" /></li><li><img src="./images/sina.png" alt="" /></li><li><img src="./images/ali.png" alt="" /></li><li><img src="./images/weixin.png" alt="" /></li></ul><router-link class="register" to="/register">立即注册</router-link></div></div></div></div></div><!-- 底部 --><div class="copyright"><ul><li>关于我们</li><li>联系我们</li><li>联系客服</li><li>商家入驻</li><li>营销中心</li><li>手机尚品汇</li><li>销售联盟</li><li>尚品汇社区</li></ul><div class="address">地址:北京市昌平区宏福科技园综合楼6层</div><div class="beian">京ICP备19006430号</div></div></div>
</template><script>export default {name: 'Login',data(){return{password:'',phone:''};},methods:{//登录的回调async userLogin(){try{//登录成功const {phone,password} = this;(phone&&password) && (await this.$store.dispatch('userLogin',{phone,password}));//登录路由组件:看路由中是否包含query参数,有 ==> 跳到query参数指定路由,没有 ==> 跳到 homelet toPath = this.$route.query.redirect || 'home';//跳转到首页this.$router.push(toPath);}catch(error){alert(error.message)}}}}
</script><style lang="less" scoped>
.login-container {.login-wrap {height: 487px;background-color: #e93854;.login {width: 1200px;height: 487px;margin: 0 auto;background: url(./images/loginbg.png) no-repeat;}.loginform {width: 420px;height: 406px;box-sizing: border-box;background: #fff;float: right;top: 45px;position: relative;padding: 20px;.tab {li {width: 50%;float: left;text-align: center;a {width: 100%;display: block;height: 50px;line-height: 50px;font-size: 20px;font-weight: 700;color: #333;border: 1px solid #ddd;box-sizing: border-box;text-decoration: none;}.current {border-bottom: none;border-top-color: #28a3ef;color: #e1251b;}}}.content {width: 380px;height: 316px;box-sizing: border-box;border: 1px solid #ddd;border-top: none;padding: 18px;form {margin: 15px 0 18px 0;font-size: 12px;line-height: 18px;.input-text {margin-bottom: 16px;span {float: left;width: 37px;height: 32px;border: 1px solid #ccc;background: url(../../assets/images/icons.png) no-repeat -10px -201px;box-sizing: border-box;border-radius: 2px 0 0 2px;}.pwd {background-position: -72px -201px;}input {width: 302px;height: 32px;box-sizing: border-box;border: 1px solid #ccc;border-left: none;float: left;padding-top: 6px;padding-bottom: 6px;font-size: 14px;line-height: 22px;padding-right: 8px;padding-left: 8px;border-radius: 0 2px 2px 0;outline: none;}}.setting {label {float: left;}.forget {float: right;}}.btn {background-color: #e1251b;padding: 6px;border-radius: 0;font-size: 16px;font-family: 微软雅黑;word-spacing: 4px;border: 1px solid #e1251b;color: #fff;width: 100%;height: 36px;margin-top: 25px;outline: none;}}.call {margin-top: 30px;ul {float: left;li {float: left;margin-right: 5px;}}.register {float: right;font-size: 15px;line-height: 38px;}.register:hover {color: #4cb9fc;text-decoration: underline;}}}}}.copyright {width: 1200px;margin: 0 auto;text-align: center;line-height: 24px;ul {li {display: inline-block;border-right: 1px solid #e4e4e4;padding: 0 20px;margin: 15px 0;}}}
}
</style>

Register.vue

<template><div class="register-container"><!-- 注册内容 --><div class="register"><h3>注册新用户<span class="go">我有账号,去 <router-link to="/login">登录</router-link></span></h3><div class="content"><label>手机号:</label><input type="text" placeholder="请输入你的手机号" v-model="phone" /><span class="error-msg">错误提示信息</span></div><div class="content"><label>验证码:</label><input type="text" placeholder="请输入验证码" v-model="code" /><button style="width: 100px; height: 38px" @click="getCode(phone)">获取验证码</button><span class="error-msg">错误提示信息</span></div><div class="content"><label>登录密码:</label><inputtype="password"placeholder="请输入你的登录密码"v-model="password"/><span class="error-msg">错误提示信息</span></div><div class="content"><label>确认密码:</label><inputtype="password"placeholder="请输入确认密码"v-model="password1"/><span class="error-msg">错误提示信息</span></div><div class="controls"><input name="m1" type="checkbox" :checked="agree" /><span>同意协议并注册《尚品汇用户协议》</span><span class="error-msg">错误提示信息</span></div><div class="btn"><button @click="userRegister">完成注册</button></div></div><!-- 底部 --><div class="copyright"><ul><li>关于我们</li><li>联系我们</li><li>联系客服</li><li>商家入驻</li><li>营销中心</li><li>手机尚品汇</li><li>销售联盟</li><li>尚品汇社区</li></ul><div class="address">地址:北京市昌平区宏福科技园综合楼6层</div><div class="beian">京ICP备19006430号</div></div></div>
</template><script>
// import map
export default {name: "Register",data() {return {//手机号phone: "",code: "",password: "",password1: "",agree: true,};},methods: {//获取验证码async getCode(phone) {//简单判断一下try {//如果获取到验证码const { phone } = this;phone && (await this.$store.dispatch("getCode", this.phone));//将组件的属性 code 替换为仓库中的验证码this.code = this.$store.state.user.code;} catch (error) {alert(error.message);}},//用户注册async userRegister() {const { phone, code, password, password1 } = this;try {if (phone && code && password == password1) {//发请求await this.$store.dispatch("userRegister", { phone, code, password });//如果成功,路由跳转this.$router.push('/login');}} catch (error) {alert(error.message);}},},
};
</script><style lang="less" scoped>
.register-container {.register {width: 1200px;height: 445px;border: 1px solid rgb(223, 223, 223);margin: 0 auto;h3 {background: #ececec;margin: 0;padding: 6px 15px;color: #333;border-bottom: 1px solid #dfdfdf;font-size: 20.04px;line-height: 30.06px;span {font-size: 14px;float: right;a {color: #e1251b;}}}div:nth-of-type(1) {margin-top: 40px;}.content {padding-left: 390px;margin-bottom: 18px;position: relative;label {font-size: 14px;width: 96px;text-align: right;display: inline-block;}input {width: 270px;height: 38px;padding-left: 8px;box-sizing: border-box;margin-left: 5px;outline: none;border: 1px solid #999;}img {vertical-align: sub;}.error-msg {position: absolute;top: 100%;left: 495px;color: red;}}.controls {text-align: center;position: relative;input {vertical-align: middle;}.error-msg {position: absolute;top: 100%;left: 495px;color: red;}}.btn {text-align: center;line-height: 36px;margin: 17px 0 0 55px;button {outline: none;width: 270px;height: 36px;background: #e1251b;color: #fff !important;display: inline-block;font-size: 16px;}}}.copyright {width: 1200px;margin: 0 auto;text-align: center;line-height: 24px;ul {li {display: inline-block;border-right: 1px solid #e4e4e4;padding: 0 20px;margin: 15px 0;}}}
}
</style>

导航守卫:router/index.js

//配置路由的地方
import store from '@/store';
import Vue from 'vue';
import VueRouter from 'vue-router';//引入路由配置文件
import routes from './routes'
//使用插件
Vue.use(VueRouter);//解决编程导航方式路由跳转方式不可重复提交相同参数的问题 ==> 重写 push 和 replace 方法
//1.先把 VueRouter 原型对象的 push 保存一份
let originPush = VueRouter.prototype.push;//重写 push | replace
//第一个参数:跳转地址和参数
VueRouter.prototype.push = function (location, resolve, reject) {if (resolve && reject) {originPush.call(this, location, resolve, reject);} else {originPush.call(this, location, () => { }, () => { });}
}//配置路由
let router = new VueRouter({//配置路由routes: routes,scrollBehavior(to, from, savedPosition) {// 始终滚动到顶部return { y: 0 }},
})===================================看这里========================================
//全局守卫:前置守卫(路由跳转前进行判断)
router.beforeEach(async (to,from,next)=>{//next,放行//仓库获取 token ,token 是登录与否的标志let token = store.state.user.token;let name  = store.state.user.userInfo.name;//1、已登录if(token){//已登录想去login?==> 不能去login,放行( next )到首页if(to.path == '/login'){next('/home')}else{//已登录不去login//仓库有用户数据 ==> 放行if(name){next()}else{//发请求,获取 userInfo,再放行try {//获取用户信息成功,放行await store.dispatch('getUserInfo');next();   } catch (error) {//获取用户信息失败,说明 token 失效了,清除仓库token和本地token,要重新登录,跳转到 登录await store.dispatch('userLogout');next('/login');} }}}else{//2、未登录:不能去交易相关、支付相关、个人中心 页面let toPath = to.path;if(toPath.indexOf('/trade')!=-1 || toPath.indexOf('/pay')!=-1 || toPath.indexOf('/center')!=-1){//跳转到登录,并保存 route 的 query 参数,确保登录完成后直接跳转到 本来想去的地址next('/login?redirect='+toPath);}else{next()}}
});export default router;

路由独享 router/router.js

//路由配置信息
......
//引入二级路由组件
......export default [//home{path: "/home",component: Home,meta: {showFooter: true}},//center{path: "/center",component: Center,meta: {showFooter: true},//注册二级路由children: [{path: "myOrder",component: MyOrder,},{path: "groupOrder",component: GroupOrder,},{path:'/center',//首次访问个人中心时,重定向到/center/myOrderredirect:'/center/myOrder'}]},//paysuccess,只有pay才能进来{path: "/paysuccess",component: PaySuccess,meta: {showFooter: true},//路由独享守卫beforeEnter:(to,from,next)=>{if(from.path == "/pay"){next()}else{//从其他路由而来,不跳转,停留在当前next(false)}}},//pay,只有trade才能进来{path: "/pay",component: Pay,meta: {showFooter: true},//路由独享守卫beforeEnter:(to,from,next)=>{if(from.path == "/trade"){next()}else{//从其他路由而来,不跳转,停留在当前next(false)}}},//trade,只有购物车才能进来{path: "/trade",component: Trade,meta: {showFooter: true},//路由独享守卫beforeEnter:(to,from,next)=>{if(from.path == "/shopCart"){next()}else{//从其他路由而来,不跳转,停留在当前next(false)}}},......//重定向,在项目跑起来的时候,访问/,立马定位到首页{path: '*',redirect: "/home"}
]

Vue —— 注册、登录相关推荐

  1. express+vue+mongodb+session 实现注册登录

    上个月写了一篇文章是 express+mongodb+vue 实现增删改查. 只是简单的实现了增删改查功能,那么今天是在那个基础之上做了扩展,首先实现的功能有如下: 1. 支持注册,登录功能,用户可以 ...

  2. 用vue+element-ui快速写一个注册登录页面

    vue+element-ui可以快速开发一个页面,免除大部分的css代码. 一.用表单来做: 1.代码: <!--基本html代码区域--> <template><div ...

  3. Vue实战篇一: 使用Vue搭建注册登录界面

    系列文章目录 Vue基础篇一:编写第一个Vue程序 Vue基础篇二:Vue组件的核心概念 Vue基础篇三:Vue的计算属性与侦听器 Vue基础篇四:Vue的生命周期(秒杀案例实战) Vue基础篇五:V ...

  4. vue+elementui 登录注册页面实现

    1.实现效果 2. 代码实现         2.1使用elementUI文档中Tabs标签页  2.2在components中新建两个文件  login.vue   register.vue    ...

  5. vue.js项目实战运用篇之抖音视频APP-第十一节: 注册登录及验证码功能

    [温馨提示]:若想了解更多关于本次项目实战内容,可转至vue.js项目实战运用篇之抖音视频APP-项目规划中进一步了解项目规划. [项目地址] 项目采用Git进行管理,最终项目将会发布到GitHub中 ...

  6. 【Vue.js】vue用户登录功能

    之前用vue实现一个网站的登录功能,这里做一个记录和总结,以下是需要实现的登录业务描述: 1.输入用户名和密码,点击登录按钮,若两者匹配,即可进入首页,首页展示登录用户的信息: 2.当用户登录后,无法 ...

  7. springboot+uniapp实现简单注册登录

    springboot+uniapp实现简单注册登录 前言 后端 新建springboot项目 配置数据库 建表,写对应类 写接口,写对应xml文件 封装返回信息,封装UUID Service层 Con ...

  8. nodejs+vue实现登录界面功能(一)

    项目描述:一开始进入登录界面,只有登录成功才可以跳转到主页面,已注册但是忘记密码的进入忘记密码页面,找回密码后进入登录界面. 技术选型:nodejs+vue+stylus 界面效果: 切换登录方式 手 ...

  9. Vue+element登录页面实现拼图验证

    Vue+element登录页面实现拼图验证 需求分析 一.导入 二.验证的意义 三.常规验证手段 详细设计 一.使用组件 二.轮子已找好,开始拼凑 效果展示 结尾 需求分析 一.导入 项目开发过程中, ...

  10. 【Java闭关修炼】SpringBoot项目-贪吃蛇对战小游戏-配置Mysql与注册登录模块2

    [Java闭关修炼]SpringBoot项目-贪吃蛇对战小游戏-配置Mysql与注册登录模块2 传统的登录验证模式 JWT登录验证方式 下载安装依赖 创建JWTUTIL JwtAuthenticati ...

最新文章

  1. linux的strace命令
  2. perl随机打乱数组
  3. c++多个对象构造和析构
  4. 剑指offer之16-20题解
  5. 在非容器(集群)环境下运行dapr
  6. delphi switch语句例子_Java 14 祭出增强版 switch,真香!!
  7. 并发编程-concurrent指南-原子操作类-AtomicBoolean
  8. python模块搜索路径_Python模块搜索路径
  9. 关于数据库的一些基本操作语句
  10. linux管理进程的数据结构,Linux 进程运行的各项指标的监测和一些管理命令的应用...
  11. 几楼电路精灵——手机端 原理图 PCB
  12. 基于变量推理的知识图路径推理分析
  13. Flink流式计算从入门到实战 三
  14. vscode远程连接服务器方法
  15. Django分组查询annotate可能遇到的坑
  16. C语言 输入三角形的三条边(a,b,c),计算三角形的面积
  17. Linux下按照时间段过滤日志
  18. SQL Server 2005 SP3正式版下载
  19. 看世界杯效应下的中东市场,开发攻略来了
  20. 集成学习_GBDT_XGBoost

热门文章

  1. php iconv 过滤特殊字体,关于iconv函数遇特殊字符的处理办法
  2. DM数据库安装及启动教程(Linux超详细版)
  3. 达人评测 i9 12900H和i5 12500h选哪个
  4. 点击事件验证码不能实现刷新的问题
  5. 9月4日科技资讯|微信支付二维码被诉侵权;AI 换脸 App「ZAO」致歉; Android 10 正式发布
  6. 【机器学习】KNN算法实战项目三:金融贷款策略分类
  7. downfile文件下载
  8. 十分钟开发一款应用,这15个国产低代码开发平台太秀了!
  9. 计算机中的树(来自百度百科)
  10. CSI室内指纹定位——相关通信名词解释