Vue.js实现一个SPA登录页面的过程【推荐】


Posted in Javascript onApril 29, 2017

技术栈

  • vue.js 主框架
  • vuex 状态管理
  • vue-router 路由管理

一般过程

在一般的登录过程中,一种前端方案是:

  1. 检查状态:进入页面时或者路由变化时检查是否有登录状态(保存在cookie或者本地存储的值);
  2. 如果有登录态则查询登录信息(uid,头像等...)并保存起来;如果没有则跳转到登录页;
  3. 在登录页面(或者登录框),校检用户输入信息是否合法;
  4. 校检通过后发送登录请求;校检不成功则反馈给用户;
  5. 登录成功则从后端数据中取出session信息保存登录状态(可能需要跳转);登录不成功则提示用户不成功;
  6. 用户做出注销操作时删除登录状态。

下面我根据列出的步骤一一分析如何做代码实现,所有在代码在https://github.com/doterlin/vue-example-login中,并带有较详细注释帮助理解代码。

在此之前假设登录页面路由为/login,登录后的路由为/user_info。这样只需要在App.vue放好router-view用于存放和渲染这两个路由。

// component/App.vue
<template>
<div class="container" id="app">
 <transition name="fade">
 <keep-alive>
  <router-view></router-view>
 </keep-alive>
 </transition>
</div>
</template>
...

并做好vue-router配置:

// js/app.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import Login from '../component/Login.vue'
import UserInfo from '../component/UserInfo.vue'
Vue.use(VueRouter);
const router = new VueRouter({
 routes: [{
 path: '/login',
 component: Login
 }, {
 path: '/user_info',
 component: UserInfo
 }]
})
...

检查状态与跳转

在两个时候我们需要检查状态:1.用户打开页面时; 2.路由发生变化时;

首先需要写好一个检查登录态的方法checkLogin:

// js/app.js
...
var app = new Vue({
 data: {},
 el: '#app',
 render: h => h(App),
 router,
 store,
 methods:{
 checkLogin(){
  //检查是否存在session
  //cookie操作方法在源码里有或者参考网上的即可
  if(!this.getCookie('session')){
  //如果没有登录状态则跳转到登录页
  this.$router.push('/login');
  }else{
  //否则跳转到登录后的页面
  this.$router.push('/user_info');
  }
 }
 }
})

为了提升用户体验,当用户打开页面时前端需要检查他是否已经登录,不需要用户再次登录。这个实现很简单,我们在vue实例的created钩子里写好:

// js/app.js
...
var app = new Vue({
 ...
 created() {
 this.checkLogin();
 },
 methods:{
 checkLogin(){
  ...
 }
 }
})

另外,路由发生变化时也需要检查登录,以下情景(路由变化)如果我们不检查登录态可能会发生错误:

  • 用户在进入页面时存在登录状态,但在做操作时正好登录过期了;
  • 用户手动删除了cookie/本地storage并做操作;
  • 用户在未登录的情况下手动输入(或者从收藏夹进入)某个需要登录的路由
  • 用户在已登录的情况下进入登录页路由

这些足够成为我们监听路由的理由,实现的话可以利用vue的watch功能:

// js/app.js
...
var app = new Vue({
 ...
 //监听路由检查登录
 watch:{
 "$route" : 'checkLogin'
 },

 //进入页面时
 created() {
 this.checkLogin();
 },

 methods:{
 checkLogin(){
  ...
 }
 }
})

至此,我们就完成了一般过程中的第1步。接下来实现如何获取用户个人信息。

获取用户信息

在成功登录后,我们一般需要从后端显示用户的一些信息,比如昵称,头像,等级等等...获取的话很简单,发一个http请求从后端拉取;但是一般这些信息会在多的路由用到(比如uid一般都需要在各个后端接口中作为参数带上),所以需要保存到全局状态中(vuex):

// component/App.vue
...
<script>
export default {
 ...
 mounted(){
 //组件开始挂载时获取用户信息
 this.getUserInfo();
 },
 methods: {
 //请求用户的一些信息
 getUserInfo(){
  this.userInfo = {
  nick: 'Doterlin',
  ulevel: 20,
  uid: '10000',
  portrait: 'images/profile.png'
  }

  //获取信息请求
  ts.$http.get(url, {
  //参数
  "params": this.userInfo
  }).then((response) => {
  //Success
  if(response.data.code == 0){
   this.$store.commit('updateUserInfo', this.userInfo); 
  }
  }, (response) => {
  //Error
  });

 }
 }
}
</script>
...

当然我们需要在之前配置好,比如在写在app.js或者单独写成store.js并在app.js引入(推荐):

// js/app.js
// Vuex配置
...
const store = new Vuex.Store({
 state: {
 domain:'http://test.example.com', //保存后台请求的地址,修改时方便(比方说从测试服改成正式服域名)
 userInfo: { //保存用户信息
  nick: null,
  ulevel: null,
  uid: null,
  portrait: null
 }
 },
 mutations: {
 //更新用户信息
 updateUserInfo(state, newUserInfo) {
  state.userInfo = newUserInfo;
 }
 }
})
...

输入校验和发送登录请求

为了防止一些不符合预期的字符和过于频繁的请求传到后台,前端要对用户的输入进行校验和防止重复请求。当然不同网站的合法字符不一样,这里只做为空时不合法的校验:

//component/Login.vue
<template>
<div class="login" id="login">
 ...
 <div class="log-email">
  <input type="text" placeholder="Email" :class="'log-input' + (account==''?' log-input-empty':'')" v-model="account"><input type="password" placeholder="Password" :class="'log-input' + (password==''?' log-input-empty':'')" v-model="password">
  <a href="javascript:;" rel="external nofollow" class="log-btn" @click="login">Login</a>
 </div>
 ...
</div>
</template>
<script>
import Loading from './Loading.vue'
export default {
 name: 'Login',
 data(){
  return {
   isLoging: false,
   account: '',
   password: ''
  }
 },
 components:{
 Loading
 },
 methods:{

  //登录逻辑
  login(){
   if(this.account!='' && this.password!=''){
    this.toLogin();
   }
  }
}
</script>
...

这里的this.toLogin就是登录请求的方法,在post密码到后端时不是直接发送,一般会按照后端定的规则加密后在发送,比如哈希算法,例子进行了的双重哈希加密,引用了js/sha1.min.js,大致实现如下:

...
  //登录请求
  toLogin(){

   //一般要跟后端了解密码的加密规则
   //这里例子用的哈希算法来自./js/sha1.min.js
   let password_sha = hex_sha1(hex_sha1( this.password ));

   //需要想后端发送的登录参数
   let loginParam = {
    account: this.account,
    password_sha
   }

   //设置在登录状态
   this.isLoging = true;

   //请求后端
   this.$http.post( 'example.com/login.php', {
   param: loginParam).then((response) => {
   if(response.data.code == 1){
    //如果登录成功则保存登录状态并设置有效期
    let expireDays = 1000 * 60 * 60 * 24 * 15;
    this.setCookie('session', response.data.session, expireDays);
    //跳转
    this.$router.push('/user_info'); 
   }
   }, (response) => {
   //Error
   });
...

这样就完成了第3,4,5个步骤了。最后一步就是注销。

注销

注销时有的需要请求后端有的不需要,关键的事要删除保存的登录状态:

// component/UserInfo.vue
...
 logout(){
  //删除cookie并跳到登录页
  this.isLogouting = true;
  //请求后端,比如logout.php
  // this.$http.post('eaxmple.com/logout.php')...
  //成功后删除cookie
  this.delCookie('session');

  //重置loding状态
  this.isLogouting = false;

  //跳转到登录页
  this.$router.push('/login/');
 }
...

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持三水点靠木!

Javascript 相关文章推荐
深入分析Cookie的安全性问题
Mar 01 Javascript
jQuery关键词说明插件cluetip使用指南
Apr 21 Javascript
浅析jQuery Ajax请求参数和返回数据的处理
Feb 24 Javascript
JavaScript每天必学之基础知识
Sep 17 Javascript
js在ie下打开对话窗口的方法小结
Oct 24 Javascript
JavaScript实现父子dom同时绑定两个点击事件,一个用捕获,一个用冒泡时执行顺序的方法
Mar 30 Javascript
解决Webpack 热部署检测不到文件变化的问题
Feb 22 Javascript
vue+axios新手实践实现登陆的示例代码
Jun 06 Javascript
vue2.x集成百度UEditor富文本编辑器的方法
Sep 21 Javascript
Vue面试题及Vue知识点整理
Oct 07 Javascript
Vue 2.0 侦听器 watch属性代码详解
Jun 19 Javascript
JS使用正则表达式提交页面验证的代码
Oct 16 Javascript
Vue.js在使用中的一些注意知识点
Apr 29 #Javascript
jQuery实现按比例缩放图片的方法
Apr 29 #jQuery
Vue开发中整合axios的文件整理
Apr 29 #Javascript
Vue.js教程之axios与网络传输的学习实践
Apr 29 #Javascript
jQuery输入框密码的显示隐藏【代码分享】
Apr 29 #jQuery
jQuery实现多张图片上传预览(不经过后端处理)
Apr 29 #jQuery
jQuery设置图片等比例缩小的方法
Apr 29 #jQuery
You might like
PHP将整个网站生成HTML纯静态网页的方法总结
2012/02/05 PHP
使用PHP强制下载PDF文件示例
2014/01/17 PHP
跟我学Laravel之视图 &amp; Response
2014/10/15 PHP
SAE实时日志接口SDK用法示例
2016/10/09 PHP
JQuery扩展插件Validate 3通过参数设置错误信息
2011/09/05 Javascript
在新窗口打开超链接的方法小结
2013/04/14 Javascript
基于jquery编写的横向自适应幻灯片切换特效的实例代码
2013/08/06 Javascript
深入理解javascript中的立即执行函数(function(){…})()
2014/06/12 Javascript
js判断浏览器是否支持html5
2014/08/17 Javascript
Jquery Ajax xmlhttp请求成功问题
2015/02/04 Javascript
jQuery基于cookie实现的购物车实例分析
2015/12/24 Javascript
基于JavaScript实现回到页面顶部动画代码
2016/05/24 Javascript
AngularJS过滤器filter用法实例分析
2016/11/04 Javascript
js中document.referrer实现移动端返回上一页
2017/02/22 Javascript
Angular中$state.go页面跳转并传递参数的方法
2017/05/09 Javascript
javascript定时器取消定时器及优化方法
2017/07/08 Javascript
AngularJS select加载数据选中默认值的方法
2018/02/28 Javascript
JavaScript 跨域之POST实现方法
2018/05/07 Javascript
vue组件化中slot的基本使用方法
2019/05/01 Javascript
使用flow来规范javascript的变量类型
2019/09/12 Javascript
BootstrapValidator实现表单验证功能
2019/11/08 Javascript
Python中低维数组填充高维数组的实现
2019/12/02 Python
tensorboard实现同时显示训练曲线和测试曲线
2020/01/21 Python
Python 实现平台类游戏添加跳跃功能
2020/03/27 Python
CSS3中线性颜色渐变的一些实现方法
2015/07/14 HTML / CSS
详解如何解决canvas图片getImageData,toDataURL跨域问题
2018/09/17 HTML / CSS
html5 外链式实现加减乘除的代码
2019/09/04 HTML / CSS
Gweniss格温妮丝女包官网:英国纯手工制造潮流包包品牌
2018/02/07 全球购物
德国童装购物网站:NICKI´S.com
2018/04/20 全球购物
美国在线家具网站:GDFStudio
2021/03/13 全球购物
给医务人员表扬信
2014/01/12 职场文书
大学生新学期计划书
2014/04/28 职场文书
幼儿园教师师德师风演讲稿:爱我所爱 无悔青春
2014/09/10 职场文书
安全教育片观后感
2015/06/17 职场文书
导游词之上海东方明珠塔
2019/09/25 职场文书
Redis 报错 error:NOAUTH Authentication required
2022/05/15 Redis