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 相关文章推荐
用CSS+JS实现的进度条效果效果
Jun 05 Javascript
javascript得到XML某节点的子节点个数的脚本
Oct 11 Javascript
基于Jquery实现的一个图片滚动切换
Jun 21 Javascript
jquery限定文本框只能输入数字即整数和小数
Nov 29 Javascript
js操作IE浏览器弹出浏览文件夹可以返回目录路径
Jul 14 Javascript
JQ技术实现注册页面带有校验密码强度
Jul 27 Javascript
jQuery实现元素拖拽并cookie保存顺序的方法
Feb 20 Javascript
JS产生随机数的用法小结
Dec 10 Javascript
vue.js组件之间传递数据的方法
Jul 10 Javascript
微信小程序ajax实现请求服务器数据及模版遍历数据功能示例
Dec 15 Javascript
JavaScript使用indexOf()实现数组去重的方法分析
Sep 04 Javascript
详解Vue+Element的动态表单,动态表格(后端发送配置,前端动态生成)
Apr 20 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
在任意字符集下正常显示网页的方法二(续)
2007/04/01 PHP
使用Xdebug调试和优化PHP程序之[1]
2007/04/17 PHP
比较详细PHP生成静态页面教程
2012/01/10 PHP
深入PHP内存相关的功能特性详解
2013/06/08 PHP
PHP多文件上传类实例
2015/03/07 PHP
php微信开发之谷歌测距
2018/06/14 PHP
php写入文件不覆盖的实例讲解
2019/09/17 PHP
什么是JavaScript
2009/08/13 Javascript
用 Javascript 验证表单(form)中的单选(radio)值
2009/09/08 Javascript
jquery dialog open后,服务器端控件失效的快速解决方法
2013/12/19 Javascript
jQuery获取和设置表单元素的方法
2014/02/14 Javascript
SuperSlide标签切换、焦点图多种组合插件
2015/03/14 Javascript
jQuery网页选项卡插件rTabs用法实例分析
2015/08/26 Javascript
JQuery统计input和textarea文字输入数量(代码分享)
2016/12/29 Javascript
js实现功能比较全面的全选和多选
2017/03/02 Javascript
vue2实现搜索结果中的搜索关键字高亮的代码
2018/08/29 Javascript
vue动态添加路由addRoutes之不能将动态路由存入缓存的解决
2019/02/19 Javascript
详解Bootstrap 学习(一)入门
2019/04/12 Javascript
vue-cli3项目展示本地Markdown文件的方法
2019/06/07 Javascript
[47:55]Ti4第二日主赛事败者组 NaVi vs EG 1
2014/07/20 DOTA
python操作MongoDB基础知识
2013/11/01 Python
python 捕获 shell/bash 脚本的输出结果实例
2017/01/04 Python
使用Django和Python创建Json response的方法
2018/03/26 Python
Python操作Sonqube API获取检测结果并打印过程解析
2019/11/27 Python
Windows上安装tensorflow  详细教程(图文详解)
2020/02/04 Python
利用HTML5实现使用按钮控制背景音乐开关
2015/09/21 HTML / CSS
英国精品买手店:Browns Fashion
2016/09/29 全球购物
巴西电子产品购物网站:Saldão da Informática
2018/01/09 全球购物
拉飞逸官网:Lafayette 148 New York
2020/07/15 全球购物
如何用JQuery进行表单验证
2013/05/29 面试题
Java基础面试题
2014/07/19 面试题
优秀毕业生自我鉴定
2014/01/19 职场文书
服装发布会策划方案
2014/05/22 职场文书
工厂仓管员岗位职责范本
2014/07/17 职场文书
推荐六本经典文学奖书籍:此生必读
2019/08/22 职场文书
python通过新建环境安装tfx的问题
2022/05/20 Python